将AST节点转换为python代码

Pep*_*zza 8 python abstract-syntax-tree

假设我有以下字符串:

code = """
if 1 == 1 and 2 == 2 and 3 == 3:
    test = 1
"""
Run Code Online (Sandbox Code Playgroud)

以下代码在 AST 中转换该字符串。

ast.parse(code)
Run Code Online (Sandbox Code Playgroud)

然后我有一棵树:

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=[])
Run Code Online (Sandbox Code Playgroud)

我想知道是否有办法将对象at.If转换为字符串if 1 == 1 and 2 == 2 and 3 == 3:

我知道它可以通过遍历子节点来完成,但是那样太复杂了。

Kal*_*lle 16

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))
Run Code Online (Sandbox Code Playgroud)

这将打印出:

if 1 == 1 and 2 == 2 and (3 == 3):
    test = 1
Run Code Online (Sandbox Code Playgroud)

请注意,原始输入可能略有不同。


noa*_*amt 7

您可以使用astunparse库,它基本上只是来自核心的代码,单独重新打包。

首先,安装库:

pip install astunparse
Run Code Online (Sandbox Code Playgroud)

然后,通过它运行 AST 模块以获取源代码。所以运行:

import ast
import astunparse

code = """
if 1 == 1 and 2 == 2 and 3 == 3:
    test = 1
"""

node = ast.parse(code)

astunparse.unparse(node)
Run Code Online (Sandbox Code Playgroud)

将输出:

'\nif ((1 == 1) and (2 == 2) and (3 == 3)):\n    test = 1\n'
Run Code Online (Sandbox Code Playgroud)


Bla*_*ane 7

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'
Run Code Online (Sandbox Code Playgroud)