给定AST,是否有获取源代码的可用库?
有没有办法把给定的Python抽象语法树(AST)转换成源代码呢?
这里有一个很好的例子,展示了如何使用Python的ast
模块,特别是NodeTransformer
。我在寻找一种方法,可以把生成的AST再转换回源代码,这样就可以直观地查看修改的内容。
4 个回答
5
我发现了一个很不错的第三方库:astunparse
,它是基于Ned在他的回答中推荐的unparse.py
。下面是一个例子:
import ast
import astunparse
code = '''
class C:
def f(self, arg):
return f'{arg}'
print(C().f("foo" + 'bar'))
'''
print(astunparse.unparse(ast.parse(code)))
运行后会得到:
class C():
def f(self, arg):
return f'{arg}'
print(C().f(('foo' + 'bar')))
另一个很酷的功能是astunparse.dump
,它可以将代码对象以漂亮的格式打印出来:
astunparse.dump(ast.parse(code))
输出结果:
Module(body=[
ClassDef(
name='C',
bases=[],
keywords=[],
body=[FunctionDef(
name='f',
args=arguments(
args=[
arg(
arg='self',
annotation=None),
arg(
arg='arg',
annotation=None)],
vararg=None,
kwonlyargs=[],
kw_defaults=[],
kwarg=None,
defaults=[]),
body=[Return(value=JoinedStr(values=[FormattedValue(
value=Name(
id='arg',
ctx=Load()),
conversion=-1,
format_spec=None)]))],
decorator_list=[],
returns=None)],
decorator_list=[]),
Expr(value=Call(
func=Name(
id='print',
ctx=Load()),
args=[Call(
func=Attribute(
value=Call(
func=Name(
id='C',
ctx=Load()),
args=[],
keywords=[]),
attr='f',
ctx=Load()),
args=[BinOp(
left=Str(s='foo'),
op=Add(),
right=Str(s='bar'))],
keywords=[])],
keywords=[]))])
7
从Python 3.9开始,ast模块提供了一个叫做unparse的功能:
这个功能可以把一个ast.AST对象转换成一段代码字符串,如果用ast.parse()再解析这段字符串,就能得到一个相同的ast.AST对象。
14
Python的源代码里有一个实现,具体在Demo/parser目录下的unparse.py文件。
编辑说明: 从Python 3.9开始,新增了ast.unparse()
这个功能,因此unparse.py文件已经被删除,所以上面的链接更新到了3.8版本。