调用未知的Python函数

时间:2009-04-13 17:12:48

标签: python

这是我为该主题提出的最佳名称,我的搜索都没有提供与该问题相关的信息。

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

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

for f in functions_to_call:
    call f

7 个答案:

答案 0 :(得分:19)

您可以使用python builtin locals()来获取本地声明,例如:

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()确保你不能调用泛型python,而使用eval,你可能最终会让用户将你的字符串设置为类似的东西:

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

或类似的,最终你的编程做你不希望的事情。与locals()和dicts一起使用类似的技巧只会给攻击者KeyErrors。

答案 1 :(得分:15)

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

functions_to_call = [int, str, float]

value = 33.5

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

答案 2 :(得分:8)

类似的东西...当我在python中查看函数指针时..

def myfunc(x):
    print x

dict = {
    "myfunc": myfunc
}

dict["myfunc"]("hello")

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

答案 3 :(得分:6)

看看getattr函数:

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

import sys

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

for f in functions_to_call:
  getattr(sys.modules[__name__], f)()

答案 4 :(得分:2)

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

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

已编辑添加:

是的,eval()通常是一个坏主意,但这正是OP所寻求的。

答案 5 :(得分:1)

请参阅eval and compile函数。

  

此函数也可用于执行任意代码对象(例如由compile()创建的代码对象)。在这种情况下,传递代码对象而不是字符串。如果代码对象已使用'exec'作为kind参数进行编译,则eval()的返回值将为None。

答案 6 :(得分: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-keys 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