有没有一个可用的库可以根据抽象语法树(AST)获取源代码?

17

有没有一种方法可以将给定的 Python 抽象语法树 (AST) 转换为源代码呢?

这里有一个很好的例子,展示了如何使用 Python 的 ast 模块,特别是 NodeTransformer。我正在寻找一种将结果 AST 转换回源代码的方法,以便可以通过视觉手段来检查更改。

4个回答

13

谢谢。看起来有些bug,但我可以把它作为一个起点使用。 - Muhammad Alkarouri
有趣的是,我没有仔细看,你看到了什么样的错误? - Ned Batchelder
算了,Python 2.7看起来没问题。我之前在2.6上尝试时发现像for ... else这样的东西有问题,但是到目前为止2.7还好。 - Muhammad Alkarouri
这是谁写的?我能找到的唯一参考资料是来自于这个README,“它们都是由我编写的[...]”,但没有提到名字。 - AnnanFay
Python3.7 是否有类似于 'ast.unparse()' 的功能? - luochen1990

7
自Python 3.9起,ast模块提供了一个unparse函数:unparse。使用它可以把ast.AST对象转换为字符串形式的代码,再使用ast.parse()解析该字符串会得到等效的ast.AST对象。

谢谢。是的,我正在关注它。看起来是最好的解决方案。 - Muhammad Alkarouri

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=[]))])

1

2
我知道这很古老,但它不能与ast模块一起使用——它只能与由compiler.ast模块生成的AST一起使用。 - David Given

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