DSb*_*ard 2 python visitor abstract-syntax-tree
NodeVisitor首先遍历AST深度优先,并在输入时仅访问每个节点一次.因此,做一些严肃的事情是有问题的.是否可以更改其默认行为?
也许有人会对一些草拟的例子感兴趣,如何做DSblizzard提出的建议,所以听到我的例子:
import ast
class RecursiveVisitor(ast.NodeVisitor):
""" example recursive visitor """
def recursive(func):
""" decorator to make visitor work recursive """
def wrapper(self,node):
func(self,node)
for child in ast.iter_child_nodes(node):
self.visit(child)
return wrapper
@recursive
def visit_Assign(self,node):
""" visit a Assign node and visits it recursively"""
print(type(node).__name__)
@recursive
def visit_BinOp(self, node):
""" visit a BinOp node and visits it recursively"""
print(type(node).__name__)
@recursive
def visit_Call(self,node):
""" visit a Call node and visits it recursively"""
print(type(node).__name__)
@recursive
def visit_Lambda(self,node):
""" visit a Function node """
print(type(node).__name__)
@recursive
def visit_FunctionDef(self,node):
""" visit a Function node and visits it recursively"""
print(type(node).__name__)
@recursive
def visit_Module(self,node):
""" visit a Module node and the visits recursively"""
pass
def generic_visit(self,node):
pass
class SimpleVisitor(ast.NodeVisitor):
""" simple visitor for comparison """
def recursive(func):
""" decorator to make visitor work recursive """
def wrapper(self,node):
func(self,node)
for child in ast.iter_child_nodes(node):
self.visit(child)
return wrapper
def visit_Assign(self,node):
""" visit a Assign node """
print(type(node).__name__)
def visit_BinOp(self, node):
""" visit a BinOp node """
print(type(node).__name__)
def visit_Call(self,node):
""" visit a Call node """
print(type(node).__name__)
def visit_Lambda(self,node):
""" visit a Function node """
print(type(node).__name__)
def visit_FunctionDef(self,node):
""" visit a Function node """
print(type(node).__name__)
@recursive
def visit_Module(self,node):
""" visit a Module node and the visits recursively, otherwise you
wouldn't see anything here"""
pass
def generic_visit(self,node):
pass
# usage example
a = """
b= lambda x: x*5 +5
def hhh(u):
b=19
return u*b
m=hhh(9*4+5)
"""
recursive_visitor = RecursiveVisitor()
simple_visitor = SimpleVisitor()
tree = ast.parse(a)
print('\nvisit recursive\n')
recursive_visitor.visit(tree)
print('\nvisit simple\n')
simple_visitor.visit(tree)
Run Code Online (Sandbox Code Playgroud)
希望有人可能会发现它很有用.
没有。您应该编写自己的访问者。递归访问所有节点相当简单,因此如果 ast 模块的内容不能为您执行此操作(并且在本例中,模块中没有任何内容可以执行您想要的操作),那么您自己执行此操作也不错。