我有一个字符串是函数名,如何在Python中引用对应的函数?

73 投票
13 回答
126656 浏览
提问于 2025-04-17 04:03

比如说,我有一个叫做 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 来执行他的字符串,他可能会在你的机器上运行任意函数

撰写回答