首页 > 解决方案 > 如何在 Python 中解析 A​​ST 以仅查找变量

问题描述

我正在寻找由用户提交的极其受限的 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'

据此,构建要放入 lambad 的变量列表的正确方法是使用 ast.Name 但是当我执行以下操作时,我会同时得到sin作为x名称。

user_submitted_fxn_example = "sin(d)>0.5"

我究竟做错了什么?

标签: pythonpython-3.xabstract-syntax-tree

解决方案


ast.Call节点代表函数调用。它们有 2 个关键属性:funcargs. 中的ast.Name节点func表示方法名称。args是 ast 节点的列表。您可能希望对 中的每个节点进行深度优先搜索args,然后查找ast.Name节点。进行 DFS 的原因是您可以输入类似sin(f(x)),其中将是包含在该字段中的f(x)另一个节点。ast.Callast.Nameargs

我建议您在此处尝试一些示例。


推荐阅读