2012-07-25 19 views
6

Tengo la siguiente clase.Métodos de llamada por cadena

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 

Si se crea una instancia de esta clase, se itera sobre una lista de cadenas y pide métodos dependiendo de la cadena real. Las cadenas en la lista tienen los nombres de los métodos correspondientes.

¿Cómo puedo hacer esto de una manera más elegante? No deseo agregar otra ruta elif para cada "función" que agregue a la lista.

+3

como nota, no llame a su lista de variables, ya que es el nombre de una función incorporada de python. Algo como 'funclist' o' flist' estaría bien;) – catchmeifyoutry

+0

Debería poner objetos de función en la lista, en lugar de strs, y simplemente llamar a cada uno. – Julian

Respuesta

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 

Para eventos privados también:

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

.

getattr(object, name[, default]) 

Devuelve el valor del atributo con nombre del objeto. el nombre debe ser una cadena. Si la cadena es el nombre de uno de los atributos del objeto, el resultado es el valor de ese atributo. Por ejemplo, getattr (x, 'foobar') es equivalente a x.foobar. Si el atributo nombrado no existe, se devuelve el valor predeterminado si se proporciona, de lo contrario se genera AttributeError.

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

+2

Creo que esta respuesta sería un poco mejor si mencionas que la magia se realizó en la función 'getattr' y proporcionó un enlace a la documentación. – mgilson

+0

También sería bueno deshacerse de la variable de lista, ya que no se usa. –

+0

@black_dragon: Genial, esto es lo que quería hacer. Pero ¿cómo accedo a métodos 'privados' como' 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

Esto se resuelve normalmente con una búsqueda de diccionario porque las funciones son los tipos de datos de primera clase en Python. Por ejemplo:

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

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

Puede usar eval que hace que su programa sea más simple y corto.

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

Usar 'exec' sería otra posibilidad. – wewa

+2

-1, eval y exec son cosas que nunca deberían aparecer en el código de Python. Son vulnerabilidades de seguridad y completamente exageradas aquí. – Julian

1

¿Por qué no usas lambdas?

Tal como digamos,

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) 

salida 9 de 11

O, usted puede hacer esto ...

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) 

le dará, 9 129

Cuestiones relacionadas