Python 从函数中返回名称未知的函数
这是正常的,但是当我们不知道字符串中的函数被调用时,问题就开始了。如果我能保证代码很小,只有一个函数,我怎么能返回这个函数呢 我想到的一个解决方案就是要求函数名为'foo'等等,所以我可以直接返回它,但它感觉很难看Python 从函数中返回名称未知的函数,python,string,return,exec,Python,String,Return,Exec,这是正常的,但是当我们不知道字符串中的函数被调用时,问题就开始了。如果我能保证代码很小,只有一个函数,我怎么能返回这个函数呢 我想到的一个解决方案就是要求函数名为'foo'等等,所以我可以直接返回它,但它感觉很难看 想法?您可以通过明确指定全局和本地执行上下文应使用的词典exec。之后,用于局部变量的函数对象应有一个单独的条目,可以在不知道其名称的情况下返回,因为它应该是字典中定义的唯一项: code = "def foo(): return 'bar'" def lol(code):
想法?您可以通过明确指定全局和本地执行上下文应使用的词典
exec
。之后,用于局部变量的函数对象应有一个单独的条目,可以在不知道其名称的情况下返回,因为它应该是字典中定义的唯一项:
code = "def foo(): return 'bar'"
def lol(code):
exec code
return foo
a = lol(code)
print a()
通常不赞成使用
exec
动态生成代码。我会重新设计代码,使其不需要exec
。我想不出另一种方法将字符串计算为Python代码。这在两个Python Verison上是否具有相同的输出?您必须将最后一行更改为print(a())
,因为print
是Python 3中的函数,而不是语句,但在其他方面,它在两个版本中的工作原理相同。我特意使用了exec
的元组形式,因为它提供了与Python 3的兼容性。如果代码字符串包含多个函数,您知道我可以用什么方法处理吗?在这种情况下,您需要某种方法来区分它们,特别是因为它们在locals\uuu
字典中的exec
之后是随机顺序。仅仅要求感兴趣的函数具有一些预定义的名称可能是最好的方法(并且是一种相当常见的插件体系结构)。
from textwrap import dedent
import types
def lol(code):
globals_ = {"__builtins__": None} # no built-ins for safety
locals_ = {}
exec(code, globals_, locals_)
if len(locals_) != 1:
raise ValueError("code didn't define exactly one item")
value = locals_.popitem()[1] # get value of the one item defined
if type(value) != types.FunctionType:
raise ValueError("code didn't define a function")
return value # return function object that was defined
my_code = dedent("""
def foo():
return 'bar'
""")
a = lol(my_code)
print(a())