2012-07-25 2 views
6

У меня есть следующий класс.Вызов методов строкой

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 

Если экземпляр этого класса будет создан, он перебирает список строк и вызовов методов в зависимости от фактической строки. Строки в списке имеют имена соответствующих методов.

Как я могу сделать это более элегантно? Я не хочу добавлять еще один elif -path для каждой «функции», которую я добавляю в список.

+3

как обратите внимание, не называйте свой список переменных, так как это имя встроенной функции python. Что-то вроде 'funclist' или' flist' было бы хорошо;) – catchmeifyoutry

+0

Вы должны поместить объекты функции в список, а не strs, и просто вызвать их. – Julian

ответ

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 

Для также частные функции:

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

.

getattr(object, name[, default]) 

Возвращает значение именованного атрибута объекта. имя должно быть строкой. Если строка является именем одного из атрибутов объекта, результатом будет значение этого атрибута. Например, getattr (x, 'foobar') эквивалентно x.foobar. Если именованный атрибут не существует, значение по умолчанию возвращается, если предусмотрено, в противном случае AttributeError будет поднят.

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

+2

Я думаю, что этот ответ был бы немного лучше, если бы вы упомянули, что магия была выполнена в функции getattr и предоставлена ​​ссылка на документацию. – mgilson

+0

Было бы также полезно избавиться от переменной списка, так как она не используется. –

+0

@black_dragon: Отлично, это то, что я хотел сделать. Но как мне получить доступ к «частным» методам, например 'def __function4 (self): напечатать« 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

Это, как правило, решается с помощью поиска словаря, поскольку функции первого класса типа данных в Python. Например:

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

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

Вы можете использовать eval, который делает вашу программу более простой и короткой.

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

Использовать 'exec' было бы еще одной возможностью. – wewa

+2

-1, eval и exec - это вещи, которые никогда не должны появляться в коде Python. Они уязвимы для безопасности и полностью переполнены здесь. – Julian

1

Почему вы не используете лямбды?

Такие, как говорят,

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) 

Выход, 9 11

ИЛИ, вы можете сделать это ...

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) 

Даст вам, 9 129