2012-07-25 62 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 2012-07-25 12:51:43

+0

你應該把函數對象放在列表中而不是strs中,然後調用每一個。 – Julian 2012-07-25 13:31:11

回答

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 2012-07-25 12:56:15

+0

因爲它沒有被使用,所以擺脫列表變量也是一件好事。 – 2012-07-25 13:03:58

+0

@black_dragon:太棒了,這是我想要做的。但是,如何訪問像'def __function4(self):print「private」'私有'方法? – wewa 2012-07-25 13:09:50

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 2012-07-25 13:19:55

+2

-1,eval和exec是永遠不會出現在Python代碼中的東西。它們是安全漏洞,在這裏完全過度。 – Julian 2012-07-25 13:29:49

1

爲什麼不使用lambdas?

如說,

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