在 python 中不使用 ast.parse 从组成元素生成 ast

Generate ast from constituent elements without using ast.parse in python

使用python ast模块,可以生成一个简单的抽象语法树如下:

import ast
module = ast.parse('x=3')

这会生成一个 Module 对象,可以使用 astor 库检索其源代码,如下所示:

import astor
astor.to_source(module)

生成

的输出
'x = 3\n'

是否可以在不使用ast.parse方法的情况下,由其组成元素构成完全相同的模块对象,从而使astor.to_source方法生成相同的源代码?如果是怎么办?

我想我刚找到它。使用 ast.dump 可以检查树的内容如下:

import astor, ast
module = ast.parse('x=3')
ast.dump(module)

这将导致以下输出揭示底层结构:

"Module(body=[Assign(targets=[Name(id='x', ctx=Store())], value=Num(n=3))])"

我们可以利用这些信息从头开始构建同一棵树,然后使用astor恢复源:

module = ast.Module(body=[ast.Assign(targets=[ast.Name(id='x', ctx=ast.Store())], value=ast.Num(n=3))])
astor.to_source(module)

输出如下:

'x = 3\n'

但是有一个问题,因为执行这个新树会导致错误:

exec(compile(module, filename='<ast>', mode="exec"))

Traceback (most recent call last): File "", line 1, in TypeError: required field "lineno" missing from stmt

要解决此问题,必须使用 ast.fix_missing_locations 方法将行号添加到每个节点。