2013-07-18 8 views
7

mam krotki który wymienia ustanawiające metody klasy, takich jak:dynamiczne połączenia Metoda W Pythonie 2.7 za pomocą struny nazwy metody

t = ('methA','methB','methC','methD','methE','methF') 

i tak dalej ..

Teraz muszę zadzwonić dynamicznie te metody opierają się na dokonanym przez użytkownika wyborze. Metody należy wywoływać w oparciu o indeks. Jeśli więc użytkownik wybierze "0", zostanie wywołana methA, jeśli zostanie wywołane "5", methF.

Moja metoda robi to w sposób następujący:

def makeSelection(self, selected): 
    #methodname = t[selected] 
    #but as this is from within the class , it has to be appended with 'self.'methodname 
    # also need to pass some arguments locally calculated here 

udało mi się wypracować coś z eval ale daje błąd i nie jest w ogóle eleganckie.

Odpowiedz

19

Jeśli wywołanie metody na obiekcie (w tym importowanych modułów) można użyć:

getattr(obj, t[i])(*args) 

Jeśli trzeba wywołać funkcję w bieżącym module

getattr(sys.modules[__name__], t[i])(*args) 

gdzie args jest listą lub krotką argumentów do wysłania, lub możesz po prostu wymienić je w wywołaniu tak jak każdą inną funkcję. Ponieważ jesteś w metodzie próbuje wywołać inną metodę na tym samym obiekcie, użyj pierwszy z self zamiast obj

getattr przyjmuje obiekt i ciąg, i robi odnośnika atrybutu w obiekcie, zwracając atrybut jeśli istnieje. obj.x i getattr(obj, 'x') osiągnąć ten sam wynik. Istnieją również funkcje setattr, hasattr i delattr, jeśli chcesz zajrzeć dalej w tego rodzaju odbicie.



Zupełnie alternatywne podejście:
Po zauważeniu ilość uwagi ta odpowiedź otrzymał, mam zamiar zaproponować inne podejście do tego, co robisz. Będę zakładać niektóre metody istnieją

def methA(*args): print 'hello from methA' 
def methB(*args): print 'bonjour de methB' 
def methC(*args): print 'hola de methC' 

Aby każda metoda odpowiadać numerem (wybór) zbudować słownika mapowania numerów z metodami sami

id_to_method = { 
    0: methA, 
    1: methB, 
    2: methC, 
} 

Biorąc pod uwagę to, id_to_method[0]() będzie powoływać methA. Jest to dwie części, pierwsza to id_to_method[0], która pobiera obiekt funkcji ze słownika, następnie wywołuje go (). Mogłem również przekazać argumentu id_to_method[0]("whatever", "args", "I", "want) w normalnym kodzie, biorąc pod uwagę powyższe was pewnie coś podobnego

choice = int(raw_input('Please make a selection')) 
id_to_method[choice](arg1, arg2, arg3) # or maybe no arguments, whatever you want 
+0

Co miłym rozwiązaniem byłoby gdybyśmy rozważa metody instancji? Tj .: wyobraź sobie, że metody, które teraz pisałeś, zawierają argumenty self: def methA (self, * args): print 'hello from methA' , ale chciałbym zbudować słownik w klasie (aby można było odczytać klucze bez konieczności o instancji), a nie w konstruktorze. Jak można to zrobić? – marcotama

+0

Można użyć metod niezwiązanych i 'getattr' podobnie jak tutaj. Nie jestem pewien, czy rozumiem, czego chcesz. –

+0

Obiekty z mojej klasy X mają alternatywne metody "eksploracji". Funkcja y łączy się z użytkownikiem i wywołuje pożądaną metodę eksploracji. Zamiast posiadania if-elif-elif -... wolałbym uzyskać dostęp do słownika, ponieważ wygląda lepiej. Ponadto, jeśli słownik był zmienną klasy, mogłem uzyskać dostęp do jego kluczy z zewnątrz. Problem polega na tym, że te metody eksploracji zależą od zmiennych instancji. Myślałem również (i zaimplementowałem) sztuczkę 'getattr', ale po prostu nie wygląda to wcale ładnie. – marcotama

Powiązane problemy