问题
Is there a way to convert a given Python abstract syntax tree (AST) to a source code?
Here is a good example of how to use Python's ast
module, specifically a NodeTransformer
. I was looking for a way to convert the resulting AST back to source, so the changes can be inspected visually.
回答1:
The Python source tree contains an implementation of this: unparse.py in the Demo/parser directory: https://github.com/python/cpython/blob/master/Tools/parser/unparse.py
回答2:
A nice third-party library I found: astunparse which is based on the unparse.py
suggested by Ned in his answer. Example:
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)))
running which yields
class C():
def f(self, arg):
return f'{arg}'
print(C().f(('foo' + 'bar')))
Another neat function is astunparse.dump
which pretty-prints the code object:
astunparse.dump(ast.parse(code))
Output:
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=[]))])
回答3:
Have a look at http://pypi.python.org/pypi/sourcecodegen/0.6.14
来源:https://stackoverflow.com/questions/3774162/given-an-ast-is-there-a-working-library-for-getting-the-source