python - 如何在 Python 中解析 AST 以仅查找变量
问题描述
我正在寻找由用户提交的极其受限的 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"
我究竟做错了什么?
解决方案
ast.Call
节点代表函数调用。它们有 2 个关键属性:func
和args
. 中的ast.Name
节点func
表示方法名称。args
是 ast 节点的列表。您可能希望对 中的每个节点进行深度优先搜索args
,然后查找ast.Name
节点。进行 DFS 的原因是您可以输入类似sin(f(x))
,其中将是包含在该字段中的f(x)
另一个节点。ast.Call
ast.Name
args
我建议您在此处尝试一些示例。
推荐阅读
- java - 是否可以使用 Swagger codegen 在多个目录中生成模型?
- grails - GORM 独立使用 Domain.findBy[property] 的问题
- architecture - 需要关于使用哪种方法进行信息亭软件开发的建议
- android - Android Studio does not recognise androidx preference library in xml
- java - android.database.sqlite.SQLiteException:靠近“UNION”:语法错误
- java - How can I disable Java EE interceptor on application start up, for example by condition from database logger=info?
- c++ - CMake - 为生成的项目定义 dll 目录或文件
- sql - 每个日期只选择一个具有 MAX(Id) 的产品
- java - Unable to load OracleDriver in a Grails application
- deployment - Do I need composer on TYPO3 production-system when my TYPO3 is in composer mode