如何在python中将字符串转换为函数?

Bob*_*Bob 34 python string function string-evaluation

例如,如果我有一个名为add like的函数

def add(x,y):
    return x+y
Run Code Online (Sandbox Code Playgroud)

我希望能够将字符串或输入转换为直接转换为该函数

w=raw_input('Please input the function you want to use')
Run Code Online (Sandbox Code Playgroud)

要么

w='add'
Run Code Online (Sandbox Code Playgroud)

有没有办法用w来引用函数add?

unu*_*tbu 46

由于您正在接受用户输入,因此最安全的方法是准确定义有效输入:

dispatcher={'add':add}
w='add'
try:
    function=dispatcher[w]
except KeyError:
    raise ValueError('invalid input')
Run Code Online (Sandbox Code Playgroud)

如果你想评估类似的字符串'add(3,4)',你可以使用安全的eval:

eval('add(3,4)',{'__builtins__':None},dispatcher)
Run Code Online (Sandbox Code Playgroud)

eval通常在应用于用户输入时可能是危险的.以上是更安全的,因为__builtins__被禁用并且locals仅限于dispatcher.比我聪明的人可能仍然会造成麻烦,但我无法告诉你如何做到这一点.

警告:即使eval(..., {'__builtins__':None}, dispatcher)不安全的应用于用户输入.如果有机会对其字符串进行评估,恶意用户可以在您的计算机上运行任意函数eval.

  • 如何使用这个答案(/sf/answers/1541474091/)建议? (3认同)

Chr*_*gan 19

一种安全的方法是从名称映射到函数.它比使用更安全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.'
Run Code Online (Sandbox Code Playgroud)


小智 13

只需使用函数参考:

def pwr(x, y):
    return x ** y

def add(x, y):
    return x + y

dispatcher = { 'pwr' : pwr, 'add' : add}

def call_func(x, y, func):
    try:
        return dispatcher[func](x, y)
    except:
        return "Invalid function"

call_func(2, 3, 'add')
Run Code Online (Sandbox Code Playgroud)

简单安全。


Foo*_*Bah 10

unutbu的解决方案是我通常会使用的,但为了完整起见:

如果你要指定函数的确切名称,你可以使用eval,虽然它非常气馁,因为人们可以做恶意的事情:

eval("add")(x,y)
Run Code Online (Sandbox Code Playgroud)


Osc*_*orz 9

内置功能eval可以满足您的需求.关于执行任意用户提供的代码的所有常见警告都适用.

如果存在有限数量的预定义函数,则应避免eval使用查找表(即Dict).绝不相信您的用户.


Hai*_* Vu 5

如果要实现一个类似shell的应用程序,用户在其中输入一些命令(例如add),并且应用程序响应(返回总和),则可以使用该cmd模块,该模块为您处理所有命令交互和调度。这是一个例子:

#!/usr/bin/env python

import cmd
import shlex
import sys

class MyCmd(cmd.Cmd):
    def do_add(self, arguments):
        '''add - Adds two numbers the print the sum'''
        x, y = shlex.split(arguments)
        x, y = int(x), int(y)
        print x + y

    def do_quit(self, s):
        '''quit - quit the program'''
        sys.exit(0)

if __name__ == '__main__':
    cmd = MyCmd()
    cmd.cmdloop('type help for a list of valid commands')
Run Code Online (Sandbox Code Playgroud)

这是一个示例运行会话:

$ python cmd_tryout.py
输入有效命令列表的帮助
(Cmd)help add add-
将两个数字相加,将打印出的总和
(Cmd)加5 3
8
(Cmd)退出

在提示符(Cmd)处,您可以发出help免费获得的命令。其他命令是addquit,分别对应于do_add()do_quit()功能。

请注意,help命令显示函数的文档字符串。docstring是紧随函数声明之后的字符串(do_add()例如,请参见)。

cmd模块不执行任何参数拆分,解析,因此您必须自己进行。该do_add()功能对此进行了说明。

这个示例程序应该足以让您入门。有关更多信息,请查找cmd帮助页面。定制提示和程序的其他方面很琐碎。