2012-07-25 87 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