Python:获取导入函数的抽象语法树?

18

假设我已经在解释器中导入了一个Python模块。如何在解释器中获取导入模块的抽象语法树(以及其中的任何函数和类)?我不想重新解析源文件。谢谢!


4
“我不想重新解析源文件。” 为什么不想重新解析?这个限制有点儿愚蠢。有原因吗? - S.Lott
这样做效率低下,似乎应该有一种方法可以使用已加载的模块来完成。 - Heinrich Schmetterling
我认为你无法在不重新解析的情况下获得AST。我相信Python会在导入时解析文件,将其转换为字节码,然后丢弃AST。实际上,如果存在pyc或pyo文件,则可能根本不会构建AST,而是直接加载字节码。如果你想要的话,你可以找到并反汇编Python字节码,但这可能没有那么有帮助。 - Walter Mundt
4
“它效率低下”?真的吗?成本微不足道,几乎无法测量。你在做什么? - S.Lott
2个回答

14
也许这个配方会给你一些启发: 一个输出Python AST人类可读版本的函数。 Python 2的选项(因为在Python 3中移除了编译器):使用compilerinspect结合(当然,仍然使用源代码):
>>> import compiler, inspect
>>> import re # for testing 
>>> compiler.parse(inspect.getsource(re))
Module('Support for regular expressions (RE). \n\nThis module provides ...

Python 3:

>>> import ast, inspect
>>> ast.parse(inspect.getsource(re))
<_ast.Module at 0x7fdcbd1ac550>

3
在Python 3中,compiler模块已被弃用。请改用ast.parse - Jordan Dimov
3
还可以考虑使用 textwrap.dedent(inspect.getsource(re)),它可以处理在其他函数或类中定义的函数。(否则多余的前导空格会使解析器出错) - pschanely
@pschanely,你的评论才是我来这里的原因。 - Nathan Chappell

0

似乎没有其他方法可以从源代码之外获取AST。如果您解释一下为什么不想重新解析源文件,也许我们可以帮忙。


对我来说,这似乎是不必要和笨重的,而且我也不一定知道路径。 - Heinrich Schmetterling
1
如果您已经导入了一个名为m的模块,则它来自的文件是m.__file__。重新阅读源代码应该很简单。正如MYYN所指出的那样,inspect也有一些有用的方法。 - Ned Batchelder

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