如何根据用户输入动态定义函数?
How can I dynamically define a function from user input?
我正在尝试根据用户输入动态生成函数。用户提供一个函数作为字符串输入,给出不同的参数,我想编写一个函数,将这个字符串变成一个可用的函数。到目前为止,我的想法是使用 exec
函数创建一个 lambda
函数,该函数使用如下字符串构造:exec("f = lambda {}:{}".format(', '.join(['x'] + parameter_list), function_string))
。例如,这会给 exec
函数一个类似 "f = lambda x, a:x+a"
的字符串。
如果我将 exec
的范围定义为 globals()
,此技术工作正常,但我希望我的函数是本地的,以便我可以执行如下操作:
def define_function(function_string, parameter_list):
exec("f = lambda {}:{}".format(', '.join(['x'] + parameter_list), function_string))
return f
或者像这样:
def define_function(function_string, parameter_list):
exec("return lambda {}:{}".format(', '.join(['x'] + parameter_list), function_string))
但是,在第一种情况下,它给出了类似“f is not defined”的错误。同时,在第二种情况下,它表示“return 只能在函数中使用”。我明白为什么会出现第二个错误,但我想知道为什么我的第一次尝试没有成功。使用 globals()
可以使它工作,但我不想使用它。
如果您对实现相同结果的其他方法有任何建议,我也很感兴趣。
编辑
使用 eval
也会引发错误:
line 9, in define_function
eval("f = lambda {}:{}".format(', '.join(['x'] + parameter_list), function_string))
File "<string>", line 1
f = lambda x, a:x+a
^
SyntaxError: invalid syntax
解决方案 1:使用 eval()
:
def get_func(param_list, result_str):
return eval("lambda {}: {}".format(', '.join(['x'] + param_list), result_str))
解决方案 2:如果您真的想使用 exec()
,请执行以下操作:
def get_func(param_list, result_str):
exec("f = lambda {}: {}".format(', '.join(['x'] + param_list), result_str))
return locals()['f']
这里有一些关于 exec
和 eval
之间区别的有用信息:What's the difference between eval, exec, and compile?
顺便说一句,我可以看到你在问题中试图做什么,值得注意的是 exec()
和 locals()
的 documentation pages 都明确警告这是行不通的。同上,如果您在交互式解释器中键入 help(locals)
,您会收到此消息:
Help on built-in function locals in module builtins:
locals()
Return a dictionary containing the current scope's local variables.
NOTE: Whether or not updates to this dictionary will affect name lookups in
the local scope and vice-versa is *implementation dependent* and not
covered by any backwards compatibility guarantees.
我正在尝试根据用户输入动态生成函数。用户提供一个函数作为字符串输入,给出不同的参数,我想编写一个函数,将这个字符串变成一个可用的函数。到目前为止,我的想法是使用 exec
函数创建一个 lambda
函数,该函数使用如下字符串构造:exec("f = lambda {}:{}".format(', '.join(['x'] + parameter_list), function_string))
。例如,这会给 exec
函数一个类似 "f = lambda x, a:x+a"
的字符串。
如果我将 exec
的范围定义为 globals()
,此技术工作正常,但我希望我的函数是本地的,以便我可以执行如下操作:
def define_function(function_string, parameter_list):
exec("f = lambda {}:{}".format(', '.join(['x'] + parameter_list), function_string))
return f
或者像这样:
def define_function(function_string, parameter_list):
exec("return lambda {}:{}".format(', '.join(['x'] + parameter_list), function_string))
但是,在第一种情况下,它给出了类似“f is not defined”的错误。同时,在第二种情况下,它表示“return 只能在函数中使用”。我明白为什么会出现第二个错误,但我想知道为什么我的第一次尝试没有成功。使用 globals()
可以使它工作,但我不想使用它。
如果您对实现相同结果的其他方法有任何建议,我也很感兴趣。
编辑
使用 eval
也会引发错误:
line 9, in define_function
eval("f = lambda {}:{}".format(', '.join(['x'] + parameter_list), function_string))
File "<string>", line 1
f = lambda x, a:x+a
^
SyntaxError: invalid syntax
解决方案 1:使用 eval()
:
def get_func(param_list, result_str):
return eval("lambda {}: {}".format(', '.join(['x'] + param_list), result_str))
解决方案 2:如果您真的想使用 exec()
,请执行以下操作:
def get_func(param_list, result_str):
exec("f = lambda {}: {}".format(', '.join(['x'] + param_list), result_str))
return locals()['f']
这里有一些关于 exec
和 eval
之间区别的有用信息:What's the difference between eval, exec, and compile?
顺便说一句,我可以看到你在问题中试图做什么,值得注意的是 exec()
和 locals()
的 documentation pages 都明确警告这是行不通的。同上,如果您在交互式解释器中键入 help(locals)
,您会收到此消息:
Help on built-in function locals in module builtins:
locals()
Return a dictionary containing the current scope's local variables.
NOTE: Whether or not updates to this dictionary will affect name lookups in
the local scope and vice-versa is *implementation dependent* and not
covered by any backwards compatibility guarantees.