2012-07-25 13 views
6

Ho la seguente classe.Metodi di chiamata per stringa

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 

Se viene creata un'istanza di questa classe, si itera su una lista di stringhe e chiama i metodi a seconda della stringa effettiva. Le stringhe nella lista hanno i nomi dei metodi corrispondenti.

Come posso farlo in un modo più elegante? Non voglio aggiungere un altro elif -path per ogni "funzione" che aggiungo alla lista.

+3

come nota, non chiamare la tua lista di variabili, poiché è il nome di una funzione built-in python. Qualcosa come 'funclist' o' flist' andrebbe bene;) – catchmeifyoutry

+0

Dovresti mettere gli oggetti funzione nella lista, piuttosto che gli strs, e chiamarli tutti. – Julian

risposta

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 

Anche per funzioni private:

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

.

getattr(object, name[, default]) 

Restituisce il valore dell'attributo denominato dell'oggetto. il nome deve essere una stringa. Se la stringa è il nome di uno degli attributi dell'oggetto, il risultato è il valore di tale attributo. Ad esempio, getattr (x, 'foobar') è equivalente a x.foobar. Se l'attributo named non esiste, viene restituito il valore predefinito se fornito, altrimenti viene sollevato l'errore AttributeError.

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

+2

Penso che questa risposta sarebbe leggermente migliore se si menzionasse che la magia è stata eseguita nella funzione 'getattr' e fornito un collegamento alla documentazione. – mgilson

+0

Sarebbe anche utile sbarazzarsi della variabile di lista, dal momento che non è utilizzata. –

+0

@black_dragon: fantastico, questo è quello che volevo fare. Ma come accedere ai metodi 'private' come' 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

Questo è di solito risolto con una ricerca dizionario perché funzioni sono tipi di dati di prima classe in Python. Ad esempio:

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

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

È possibile utilizzare eval che rendono il programma più semplice e breve.

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

Utilizzare 'exec' sarebbe un'altra possibilità. – wewa

+2

-1, eval ed exec sono cose che non dovrebbero mai apparire in codice Python. Sono vulnerabilità di sicurezza e completamente eccessivo qui. – Julian

1

Perché non usi lambda?

Come dire,

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) 

uscita, 9 11

O, si può fare questo ...

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) 

vi darà, 9 129

Problemi correlati