Вы можете использовать методы ast.NodeTransformer
и visit_Assign
и visit_AugAssign
.Вот краткая демонстрация:
import ast
import inspect
def f():
a = 1
# Something else
print("test")
a += 1
class CustomNodeTransformer(ast.NodeTransformer):
def visit_Assign(self, node):
print("\nvisit_Assign")
print(node.__dict__)
print(node.targets[0].__dict__)
print(node.value.__dict__)
return node
def visit_AugAssign(self, node):
print("\nvisit_AugAssign")
print(node.__dict__)
print(node.target.__dict__)
print(node.value.__dict__)
return node
nodes = ast.parse(inspect.getsource(f))
CustomNodeTransformer().visit(nodes)
Что печатает:
visit_Assign
{'targets': [<_ast.Name object at 0x7fdca78a10b8>], 'value': <_ast.Num object at 0x7fdca78a1080>, 'lineno': 2, 'col_offset': 4}
{'id': 'a', 'ctx': <_ast.Store object at 0x7fdca78b0198>, 'lineno': 2, 'col_offset': 4}
{'n': 1, 'lineno': 2, 'col_offset': 8}
visit_AugAssign
{'target': <_ast.Name object at 0x7fdca7585048>, 'op': <_ast.Add object at 0x7fdca78b0f60>, 'value': <_ast.Num object at 0x7fdca7585080>, 'lineno': 5, 'col_offset': 4}
{'id': 'a', 'ctx': <_ast.Store object at 0x7fdca78b0198>, 'lineno': 5, 'col_offset': 4}
{'n': 1, 'lineno': 5, 'col_offset': 9}
Относительно примера:
- Узлы дерева AST взяты из источникакод функции
f
в качестве примера.Вы можете использовать любое дерево, которое вам нравится. visit_Assign
имеет список targets
в случае присвоений, например a = b = 1
.В примере просто используется targets[0]
. NodeTransformer
, предназначенный для изменения узлов.Так что без return
в описанных выше методах это будет похоже на return None
, который удалит узлы из дерева. - Если ни один из вашего кода не должен изменять что-либо из узлов, то в этом нет необходимостив любом случае использовать
ast.NodeTransformer
, и вместо этого вы можете использовать ast.NodeVisitor
.Тогда вам не нужно return
.