我在玩AST操纵。目前我正在尝试从输入AST中删除某些节点。我认为NodeTransformer类是一个合适的工具。遗憾的是,它的行为并不像预期的那样。在
“NodeTransformer将遍历AST并使用visitor方法的返回值来替换或删除旧节点。如果visitor方法的返回值为None,则该节点将从其位置删除,否则将用返回值替换它。”
现在看看我的程序:import _ast
import ast
import sys
#ast transformer
class MyTransformer(ast.NodeTransformer):
def iterate_children(self, node):
"""
helper
"""
children = ast.iter_child_nodes(node)
for c in children:
self.visit(c)
def generic_visit(self, node):
"""
default behaviour
"""
print("visiting: "+node.__class__.__name__)
self.iterate_children(node)
return node
def visit_For(self, node):
"""
For nodes: replace with nothing
"""
print("removing a For node")
return None
#read source program
filename = sys.argv[1]
with open (filename, "r") as myfile:
source = str(myfile.read())
#compile source to ast
m = compile(source, "", "exec", _ast.PyCF_ONLY_AST)
#do ast manipulation
t = MyTransformer()
t.visit(m)
# fix locations
m = ast.fix_missing_locations(m)
#visualize the resulting ast
#p = AstPrinter()
#p.fromAst(m)
#execute the transformed program
print("computing...")
codeobj = compile(m, '', 'exec')
exec(codeobj)
以下是输入文件:
^{pr2}$
结果是:visiting: Module
visiting: Assign
visiting: Name
visiting: Store
visiting: List
visiting: Num
visiting: Num
visiting: Num
visiting: Num
visiting: Load
visiting: Assign
visiting: Name
visiting: Store
visiting: Num
removing a For node
visiting: Expr
visiting: Call
visiting: Name
visiting: Load
visiting: Name
visiting: Load
computing...
6
我需要“0”,因为循环已被删除。但有一个“6”(=0+1+2+3)。在
有人知道为什么吗?在
Python版本:3.2.3
()中的数字表示输入程序中的行号。此处未提供图像绘制代码;请忽略“根”节点。如您所见,For循环仍然存在。在
谢谢你的阅读!在
更新21.8:
我在python邮件列表上发布了这个问题的链接(python-list@python.org). 好像我写的太多了。如果没有儿童访客,它将按预期工作。在
MyTransformer的完整源代码:class MyTransformer(ast.NodeTransformer):
def visit_For(self, node):
"""
For nodes: replace with nothing
"""
print("removing a For node")
return None