将AST节点转换为Python代码

15

假设我有以下字符串:

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:

我知道可以通过遍历子节点来完成,但这样做变得太复杂了。


2
遍历子节点是我唯一知道的方法。 - inspectorG4dget
有第三方工具可以尝试实现,例如astor - AChampion
3个回答

15
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

请注意,原始输入可能会有轻微差异。

12

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'

7
你可以使用astunparse库,它基本上只是从核心代码中重新打包的单独的代码。
首先,安装该库:
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'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接