Преобразовать узел AST в код Python
Предположим, у меня есть следующая строка:
code = """
if 1 == 1 and 2 == 2 and 3 == 3:
test = 1
"""
Следующий код преобразует эту строку в AST.
ast.parse(code)
Тогда у меня есть дерево, как:
Module(body=[<_ast.If object at 0x100747358>])
If(test=BoolOp(op=And(), values=[<_ast.Compare object at 0x100747438>, <_ast.Compare object at 0x100747a90>, <_ast.Compare object at 0x100747d68>]), body=[<_ast.Assign object at 0x100747e48>], orelse=[])
Я хочу знать, есть ли способ конвертировать объект at.If
в строку if 1 == 1 and 2 == 2 and 3 == 3:
Я знаю, что это можно сделать, пересекая дочерний узел, но таким образом он становится слишком сложным.
3 ответа
Python 3.9 представил ast.unparse, который делает именно это, то есть меняет
ast.parse
. Используя ваш пример:
import ast
code = """
if 1 == 1 and 2 == 2 and 3 == 3:
test = 1
"""
tree = ast.parse(code)
print(ast.unparse(tree))
Это распечатает:
if 1 == 1 and 2 == 2 and (3 == 3):
test = 1
Обратите внимание, что исходные данные могут немного отличаться.
ast.get_source_segment
был добавлен в python 3.8:
>>> import ast
>>> code = """
>>> if 1 == 1 and 2 == 2 and 3 == 3:
>>> test = 1
>>> """
>>> node = ast.parse(code)
>>> ast.get_source_segment(code, node.body[0])
'if 1 == 1 and 2 == 2 and 3 == 3:\n test = 1'
Вы можете использовать unparse библиотеку, которая была в основном просто кодом из ядра, переупакованным индивидуально.
Сначала установите библиотеку:
pip install astunparse
Затем запустите модуль AST, чтобы получить исходный код. Так работает:
import ast
import astunparse
code = """
if 1 == 1 and 2 == 2 and 3 == 3:
test = 1
"""
node = ast.parse(code)
astunparse.unparse(node)
Будет выводить:
'\nif ((1 == 1) and (2 == 2) and (3 == 3)):\n test = 1\n'