Python
NodeVisitor
Learn the visitor pattern with ast.NodeVisitor.
What is NodeVisitor?
ast.NodeVisitor is a class for walking an AST in an orderly way. You override visit_<type> methods to write custom behavior for each node type.
For example defining def visit_Name(self, node) makes the visitor call this method on every Name node. The self.generic_visit(node) call ensures children are also visited; forgetting it skips the depth. This pattern is ideal for tools that need type-based handling: a linter can warn on every Call node.
visit_ methods
For each node type you define a visit_<type> method. Python looks at the type name and calls the matching method when it encounters a node.
For example visit_Name runs on Name nodes, visit_Constant on constant value nodes. Inside the method you access fields like node.id or node.value. The self.generic_visit(node) call continues descending into children; omitting it stops the visitor at that branch. You can define multiple visit_ methods for complex analysis.
Exercise Collect names with NodeVisitor
Import the module with import ast. Write a NameCollector(ast.NodeVisitor) class. In __init__ set self.names = []. In visit_Name(self, node) do self.names.append(node.id) and call self.generic_visit(node). Build the tree with ast.parse("x = 1\ny = 2"), run the visitor with .visit(tree), print the names list.
Show example solution
import ast
class NameCollector(ast.NodeVisitor):
def __init__(self):
self.names = []
def visit_Name(self, node):
self.names.append(node.id)
self.generic_visit(node)
tree = ast.parse("x = 1\ny = 2")
c = NameCollector()
c.visit(tree)
print(c.names)
Test yourself
-
Complete the NodeVisitor definition
class Collector(____):
pass
Show answer
class Collector(ast.NodeVisitor):
pass
-
Match NodeVisitor concepts
- visit_Name
- Name nodes
- generic_visit
- Descends to children
- NodeVisitor
- Visitor base
- node.id
- Name text
-
When is visit_Name called?
class C(ast.NodeVisitor):
def visit_Name(self, node):
print(node.id)
tree = ast.parse("x = 1")
C().visit(tree)
- Automatically on every Name node
- Only when the class is defined
- When the program starts
- Only on errors
Show answer
Automatically on every Name node — visit_Name fires automatically when the visitor encounters a Name node.
Next lesson: NodeTransformer