我正在测试一些代码来回答Possible to turn an input string into a callable function object in Python?,问题以重复的形式结束了,但我在源代码答案中找不到该问题的答案。你知道吗
关于这个问题有很多类似的答案,但是没有一个解决如何从string
返回function
的问题。exec()
不返回function.
它只执行任意代码。你知道吗
我的问题是,这种将字符串转换为函数并作为函数对象返回的方法是否正确?你知道吗
my_string = "def add5(x):return x + 5"
def string_to_func(my_string):
exec(my_string)
for var_name, var in locals().items():
if callable(var):
return var
print("no callable in string")
#fallback code.
add5 = string_to_func(my_string)
print(add5(3))
p.S.:如果重新打开原始问题,我将删除此问题。你知道吗
粗略地说,如果假设输入是完全受信任的,并且提供的字符串是有效的Python语法,将生成一个可调用函数,并且如果
exec
不能使用,则可以提供类似的内容示例:
输出
代码确保提供的源代码是单个函数定义,并假设生成的字节码的组织(即,仅适用于当前版本的Python中内置的编译器,其中,生成的字节码将源中定义的单个函数的代码对象放在
co_consts
的第0个元素中。这个答案的previous version使用了exec
(提问者“无论如何都不是exec的忠实粉丝”),以一种将结果绑定到特定目标的方式完成,这种方法应该更可靠,因为它不触及这个较低层次的结构,尽管这里使用的ast
模块的健全性检查可以包含在原始版本中。你知道吗还要注意,这个答案只适用于python3+。你知道吗
进一步编辑:
关于
exec
的用法被假定为执行任意代码(在固定输入上)的评论,实际上我还是有点恼火,因为它的实际功能常常被误解。在这种特殊情况下,如果验证只接受特定的源,则不一定意味着每个语句都立即执行。尤其是在这种情况下(在我最初的懒散回答中,并不能保证这一点,但这正是真正理解框架实际上在做什么对于在语言框架中进行代码动态编译非常重要的地方,考虑到需要更高级别的“安全性”(在事实否定它之后立即执行函数,因此我最初没有实现),使用ast
是在编辑中完成的,现在客观上更好了)。你知道吗那么,调用
exec(co)
与原始示例在给定单个函数定义的源输入时所做的本质上是什么样的呢?可以通过如下方式查看字节码来确定:它所做的一切就是加载代码对象,使其成为一个适当的函数,并将结果赋给
my_function
(在当前相关的范围内),本质上就是这样。是的,正确的方法是验证源代码是否确实是这样的函数定义(因为通过检查AST进行的验证比只存在一条语句的更简单的验证更安全),然后在特定的dict
上运行exec并从中提取赋值。在这种情况下,以这种方式使用exec
并不是天生的不安全(或更安全),因为所提供的任何函数都会立即执行。你知道吗相关问题 更多 >
编程相关推荐