我希望构建一个由用户提交的极其受限的lambda处理器。我正在使用以下代码执行此操作:
import ast, operator
from math import *
#make a list of safe functions
safe_list = ["math", "lambda"]
# use the list to filter the local namespace
safe_dict = dict([(k, locals().get(k, None)) for k in safe_list])
all_args = []
user_submitted_fxn_example = "d>15"
node = ast.parse(user_submitted_fxn_example, mode="eval")
for elem in ast.walk(node):
if isinstance(elem, ast.Name):
all_args.append(str(elem.id))
lambda_string = f"lambda {','.join(all_args)}: {fxn}"
a = eval(f"lambda {','.join(all_args)}: {fxn}", {"__builtins__": None}, safe_dict)
print(a(11)) # => Correctly reports 'False'
根据this,构建要放入lambad中的变量列表的正确方法是使用ast.Name,但是当我执行以下操作时,我将sin
和x
作为名称
user_submitted_fxn_example = "sin(d)>0.5"
我做错了什么
ast.Call
节点表示函数调用。它们有两个关键属性:func
和args
。func
中的ast.Name
节点表示方法名称args
是ast节点的列表。您可能希望对args
中的每个节点执行深度优先搜索,然后查找ast.Name
节点。执行DFS的原因是您可以有一个类似sin(f(x))
的输入,其中f(x)
将是另一个ast.Call
节点,它在args
字段中包含ast.Name
我建议您使用一些示例here
相关问题 更多 >
编程相关推荐