我有一个字符串是函数名,如何在Python中引用对应的函数?
比如说,我有一个叫做 add
的函数,内容是这样的:
def add(x,y):
return x+y
我想要能够把一个字符串或者输入直接指向这个函数,比如说:
w=raw_input('Please input the function you want to use')
或者
w='add'
有没有什么方法可以用 w 来指代这个 add
函数呢?
13 个回答
18
unutbu的解决方案是我通常会使用的,但为了全面起见,我想补充一下:
如果你要指定函数的确切名称,可以使用 eval
,不过这并不推荐,因为这样可能会让人做一些恶意的事情:
eval("add")(x,y)
21
一种安全的方法是将名字和函数对应起来。这比使用 eval
要安全得多。
function_mappings = {
'add': add,
}
def select_function():
while True:
try:
return function_mappings[raw_input('Please input the function you want to use')]
except KeyError:
print 'Invalid function, try again.'
72
因为你在处理用户输入,所以最安全的做法是明确规定什么样的输入是有效的:
dispatcher={'add':add}
w='add'
try:
function=dispatcher[w]
except KeyError:
raise ValueError('invalid input')
如果你想评估像 'add(3,4)'
这样的字符串,你可以使用 安全评估:
eval('add(3,4)',{'__builtins__':None},dispatcher)
一般来说,使用 eval
来处理用户输入是有风险的。 上面的做法更安全,因为 __builtins__
被禁用了,locals
也限制在 dispatcher
内。可能有比我更聪明的人能找到漏洞,但我不知道具体怎么做。
警告:即使是 eval(..., {'__builtins__':None}, dispatcher)
对用户输入来说也是不安全的。如果恶意用户有机会通过 eval
来执行他的字符串,他可能会在你的机器上运行任意函数。