все Python 3astпонятие
ast.NodeTransformer
вспомогательные функции
Подкласс NodeVisitor для изменения дерева: значение, возвращённое visit_*, заменяет узел, а None удаляет его.
Синтаксис
class T(ast.NodeTransformer):
def visit_Name(self, node): return node
tree = T().visit(tree)
Забытый return в методе visit_* — частая ошибка: метод вернёт None, и узел молча исчезнет из дерева. Для инструкций можно вернуть список узлов — он встанет на место одной. Новые узлы не имеют lineno, и compile() упадёт с TypeError, пока не вызвать ast.fix_missing_locations(tree). Как и в NodeVisitor, детей нужно обходить самому через generic_visit.
Примеры
import ast
class Oops(ast.NodeTransformer):
def visit_Expr(self, node):
node.value = ast.Constant(0)
tree = Oops().visit(ast.parse('print(1)\nx = 2'))
print(ast.unparse(tree)) # → x = 2 — print исчез
import ast
class Upper(ast.NodeTransformer):
def visit_Constant(self, node):
if isinstance(node.value, str):
return ast.Constant(node.value.upper())
return node
tree = Upper().visit(ast.parse("print('hi')"))
try:
compile(tree, '<ast>', 'exec')
except TypeError:
print('нет lineno') # → нет lineno
exec(compile(ast.fix_missing_locations(tree), '<ast>', 'exec')) # → HI
См. также
Открыть в полном глоссарииdocs.python.orgСообщить о неточности