2009-04-13 74 views
6

这是我可以为该主题提出的最好名称,我的搜索都没有提供与该问题相关的信息。调用未知的Python函数

如何调用一个函数从字符串,即

functions_to_call = ["func_1", "func_2", "func_3"] 

for f in functions_to_call: 
    call f 
+0

当你似乎知道你想从列表中调用它们的函数时,它是如何未知的函数 – 2009-04-13 17:45:21

+0

函数名可能来自外部源,如文本文件。 – gregturn 2009-04-13 18:37:23

+0

这意味着它是一个运行游戏的半抽象系统(所以我可以重复使用它),因此它们将会接近文本文件。 – Teifion 2009-04-13 22:46:15

回答

2
functions_to_call = ["func_1", "func_2", "func_3"] 

for f in functions_to_call: 
    eval(f+'()') 

编辑补充:

是,eval()函数通常是一个坏主意,但是这是什么OP正在寻找。

+0

这工作完美,我不知道为什么它有这么几个upvotes。 – Teifion 2009-04-13 17:36:51

+0

-1没有提到eval的使用是一个糟糕的主意。确实是 – nosklo 2009-04-13 17:38:46

+2

。在这里没有理由使用eval()。 '本地人()[f]()'会很好。这仍然是一个非常可疑的方式,但比eval()更好。 – bobince 2009-04-13 18:13:04

15

你怎么知道要调用的函数的名字?存储功能而不是名称:

functions_to_call = [int, str, float] 

value = 33.5 

for function in functions_to_call: 
    print "calling", function 
    print "result:", function(value) 
+0

我可以解释有关确切程序的所有内容,但我认为这会浪费空间并分散手头的具体问题。 – Teifion 2009-04-13 17:19:15

+0

函数在问题中存储为字符串,而不是在答案中存储,所以答案并不完全正确...... – sykora 2009-04-13 17:21:13

+1

@sykora ...但是如果您可以扭转问题的要求,它确实显示出更好的方式一点点。 – 2009-04-13 17:24:02

1

查看eval and compile的功能。

该函数也可以用来执行任意代码对象(比如由compile()创建的那些对象)。在这种情况下,传递一个代码对象而不是一个字符串。如果代码对象已经用'exec'作为kind参数编译,则eval()的返回值将是None。

+0

-1没有提及exec/eval的使用是一个糟糕的主意。 – nosklo 2009-04-13 17:37:35

8

类似的东西...当我看着在Python函数指针..

def myfunc(x): 
    print x 

dict = { 
    "myfunc": myfunc 
} 

dict["myfunc"]("hello") 

func = dict.get("myfunc") 
if callable(func): 
    func(10) 
+0

如果你确实需要一个字符串 – nosklo 2009-04-13 17:35:19

+0

“函数指针”,那么+1调度字典是一个很好的方法吗?没有这样的事。 – 2009-04-13 21:26:46

+0

是的...我知道...我正在寻找相当于... – LB40 2009-04-14 12:45:09

19

您可以使用Python内置的当地人()来获取局部声明,如:

def f(): 
    print "Hello, world" 

def g(): 
    print "Goodbye, world" 

for fname in ["f", "g"]: 
    fn = locals()[fname] 
    print "Calling %s" % (fname) 
    fn() 

您可以使用“imp”模块从用户指定的python文件加载函数,这给您更多的灵活性。

使用locals()确保你不能叫通用蟒蛇,而使用的eval,你可以与用户最终的字符串设定为像某种不利:

f = 'open("/etc/passwd").readlines' 
print eval(f+"()") 

或相似,并且结了你的编程做你认为不可能的事情。通常使用类似的技巧与本地人()和字典,只会给攻击者KeyErrors。

+0

你是一个恶性混蛋nosklo。他*做了很好的解释 – mpen 2009-04-13 18:13:30

+0

@Mark:的确如此。我评论了错误的答案,对不起。删除。 – nosklo 2009-04-13 18:26:08

1

不要使用eval!它几乎从来没有要求的,在Python函数只是属性和其他事物一样,而且无论是在一类使用getattr,或通过locals()访问:

>>> print locals() 
{'__builtins__': <module '__builtin__' (built-in)>, 
'__doc__': None, 
'__name__': '__main__', 
'func_1': <function func_1 at 0x74bf0>, 
'func_2': <function func_2 at 0x74c30>, 
'func_3': <function func_3 at 0x74b70>, 
} 

由于这是一本字典,你可以通过dict-获得的功能键func_1func_2func_3

>>> f1 = locals()['func_1'] 
>>> f1 
<function func_1 at 0x74bf0> 
>>> f1() 
one 

所以,而不诉诸解决EVAL:

>>> def func_1(): 
...  print "one" 
... 
>>> def func_2(): 
...  print "two" 
... 
>>> def func_3(): 
...  print "three" 
... 
>>> functions_to_call = ["func_1", "func_2", "func_3"] 
>>> for fname in functions_to_call: 
...  cur_func = locals()[fname] 
...  cur_func() 
... 
one 
two 
three