Преобразовать узел 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'
Другие вопросы по тегам