如何编写 ast.NodeTransformer 将 a=1 转换为函数调用 a=variables("a")?
How can I write an ast.NodeTransformer to convert a=1 to a function call a=variables("a")?
python 文档和 greentreesnakes 表明可以使用 ast.NodeTransformer
通过 AST 更改 python 代码:
我想将 a=1
之类的作业更改为 a=variables(1)
。
我对 ctx
是什么以及何时需要它感到有点困惑,astor 的输出似乎没有它,但似乎需要它。
您不一定需要 NodeTransformer
来执行此操作。如果您已经拥有 AST
并且知道该节点(在本例中为 Assign
节点),您可以按如下方式就地修改。
import ast
src = 'a = 1'
code = 'variables(1)'
tree = ast.parse(src)
assign_node = tree.body[0]
assign_node.value = ast.parse(code).body[0].value
更新后的 AST
可以进一步用于您的任何目的。例如,您可以生成源代码(在上例中使用 astor
模块作为 astor.to_source(tree)
)。 NodeTransformer
如果您需要在给定条件的情况下查找节点,则非常方便。它具有类似于 NodeVisitor
的 visit_*
功能,可让您就地执行此操作。如下所示:
from ast import parse, NodeTransformer
class ChangeAssignment(NodeTransformer):
def visit_Assign(self, node):
if assign_node.targets[0].id == 'a':
node.value = parse('variables(1)').body[0].value
return node
src = 'a = 1'
t = ChangeAssignment()
tree = parse(src)
tree = t.visit(tree)
变量的ctx
决定了它是用于加载、存储还是删除变量。如果你直接创建节点(上面我使用 parse
隐式创建节点),则需要它。对于修改 AST
或生成源代码(如 astor.to_source
),使用什么 ctx
并不重要。但是,如果你直接将 AST
传递给 Python compile
函数,如果没有使用正确的 ctx
它会报错。
python 文档和 greentreesnakes 表明可以使用 ast.NodeTransformer
通过 AST 更改 python 代码:
我想将 a=1
之类的作业更改为 a=variables(1)
。
我对 ctx
是什么以及何时需要它感到有点困惑,astor 的输出似乎没有它,但似乎需要它。
您不一定需要 NodeTransformer
来执行此操作。如果您已经拥有 AST
并且知道该节点(在本例中为 Assign
节点),您可以按如下方式就地修改。
import ast
src = 'a = 1'
code = 'variables(1)'
tree = ast.parse(src)
assign_node = tree.body[0]
assign_node.value = ast.parse(code).body[0].value
更新后的 AST
可以进一步用于您的任何目的。例如,您可以生成源代码(在上例中使用 astor
模块作为 astor.to_source(tree)
)。 NodeTransformer
如果您需要在给定条件的情况下查找节点,则非常方便。它具有类似于 NodeVisitor
的 visit_*
功能,可让您就地执行此操作。如下所示:
from ast import parse, NodeTransformer
class ChangeAssignment(NodeTransformer):
def visit_Assign(self, node):
if assign_node.targets[0].id == 'a':
node.value = parse('variables(1)').body[0].value
return node
src = 'a = 1'
t = ChangeAssignment()
tree = parse(src)
tree = t.visit(tree)
变量的ctx
决定了它是用于加载、存储还是删除变量。如果你直接创建节点(上面我使用 parse
隐式创建节点),则需要它。对于修改 AST
或生成源代码(如 astor.to_source
),使用什么 ctx
并不重要。但是,如果你直接将 AST
传递给 Python compile
函数,如果没有使用正确的 ctx
它会报错。