2012-07-25 11 views
6

Mam następujące klasy.Metody połączeń według łańcucha

func_list= ["function1", "function2", "function3"] 

class doit(object): 
    def __init__(self): 
     for item in func_list: 
      if item == "function1": 
       self.function1() 
      elif item == "function2": 
       self.function2() 
      elif item == "function3": 
       self.function3() 

    def function1(self): 
     #do this 
     pass 
    def function2(self): 
     #do that 
     pass 
    def function3(self): 
     pass 

Utworzenie instancji tej klasy powoduje iterację na liście łańcuchów i wywołań metod w zależności od rzeczywistego ciągu znaków. Łańcuchy na liście mają nazwy odpowiednich metod.

Jak mogę to zrobić w bardziej elegancki sposób? Nie chcę dodawać kolejnej ścieżki elif dla każdej "funkcji" dodanej do listy.

+3

jako zauważ, nie wywołuj swojej listy zmiennych, ponieważ jest to nazwa wbudowanej funkcji Pythona. Coś w rodzaju 'funclist' lub' flist' byłoby w porządku;) – catchmeifyoutry

+0

Powinieneś umieścić obiekty funkcji na liście, zamiast w strs i po prostu wywołać każdy z nich. – Julian

Odpowiedz

10
func_list= ["function1", "function2", "function3"] 

class doit(object): 
    def __init__(self): 
     for item in func_list: 
      getattr(self, item)() 
    def function1(self): 
     print "f1" 
    def function2(self): 
     print "f2" 
    def function3(self): 
     print "f3" 



>>> doit() 
f1 
f2 
f3 

Dla także prywatne funkcje:

for item in func_list: 
    if item.startswith('__'): 
     getattr(self, '_' + self.__class__.__name__+ item)() 
    else: 
     getattr(self, item)() 

.

getattr(object, name[, default]) 

Zwraca wartość nazwanego atrybutu obiektu. nazwa musi być łańcuchem. Jeśli ciąg jest nazwą jednego z atrybutów obiektu, wynikiem jest wartość tego atrybutu. Na przykład getattr (x, 'foobar') jest odpowiednikiem x.foobar. Jeśli nazwany atrybut nie istnieje, zwracana jest wartość domyślna, jeśli została podana, w przeciwnym razie zostanie podniesiony atrybut AttributeError.

http://docs.python.org/library/functions.html#getattr

+2

Myślę, że ta odpowiedź byłaby nieco lepsza, gdybyś wspomniała, że ​​magia została wykonana w funkcji 'getattr' i zawierała link do dokumentacji. – mgilson

+0

Byłoby również dobrze pozbyć się zmiennej listy, ponieważ nie jest używana. –

+0

@black_dragon: Świetnie, właśnie to chciałem zrobić. Ale jak uzyskać dostęp do "prywatnych" metod takich jak 'def __function4 (self): print" private "? – wewa

0
class doit(object): 
    def __init__(self, func_list): 
     for func in func_list: 
      func(self) 
    #insert other function definitions here 

func_list = [doit.function1, doit.function2, doit.function3] 
foo = doit(func_list) 
2

Zazwyczaj jest to rozwiązano tego słownika ponieważ funkcje pierwszej klasy typów danych w Pythonie. Na przykład:

# map string names to callable functions 
dispatch = {'func1': func1, 'func2': func2, ...} 

want_to_call = 'func1' 
dispatch[want_to_call](args) 
-2

Możesz użyć eval, który sprawia, że ​​twój program jest prostszy i krótszy.

list= ["function1", "function2", "function3"] 

class doit(object): 
    def __init__(self): 
     for item in list: 
      eval(item)() 
    def function1(self): 
     print "f1" 
    def function2(self): 
     print "f2" 
    def function3(self): 
      print "f3" 
+0

Używanie 'exec' byłoby inną możliwością. – wewa

+2

-1, eval i exec to rzeczy, które nigdy nie powinny pojawiać się w kodzie Pythona. Są to luki w zabezpieczeniach i tutaj całkowicie przesadzają. – Julian

1

Dlaczego nie używasz lambdas?

Taki Jak mówią,

def func1(a): 
    return a ** 2 

def func2(a, b): 
    return a ** 3 + b 

dic = {'Hello':lambda x: func1(x), 'World':lambda x,y: func2(x, y)} #Map functions to lambdas 
print dic['Hello'](3) 
print dic['World'](2,3) 

wyjścia, 9 11

OR, można to zrobić ...

class funs(): 
    def func1(self, a): 
     return a ** 2 

    def func2(self, a, b): 
     return a ** 3 + b 

f = funs() 
dic = {'Hello': lambda x: f.func1(x), 'World': lambda x,y: f.func2(x,y)} 
print dic['Hello'](3) 
print dic['World'](5,4) 

daje 9 129

Powiązane problemy