如何在 Python 中获取完整的 AST?
我喜欢 _ast 模块提供的选项,它真的很强大。 有没有办法从中获取完整的 AST?
例如,如果我获得以下代码的 AST:
import os
os.listdir(".")
通过使用:
ast = compile(source_string,"<string>","exec",_ast.PyCF_ONLY_AST)
ast 对象的主体将有两个元素,一个 import 对象和一个 expr 对象。 但是,我想更进一步,获取 import 和 listdir 的 AST,换句话说,我想制作 _ast 下降到可能的最低水平。
我认为这种事情应该是可能的,这是合乎逻辑的。 问题是如何?
编辑:通过尽可能最低的级别,我并不是指访问“可见”的内容。 我还想获取 listdir 实现的 AST:例如 stat 以及可能为其执行的其他函数调用。
I like the options offered by the _ast module, it's really powerful. Is there a way of getting the full AST from it?
For example, if I get the AST of the following code :
import os
os.listdir(".")
by using :
ast = compile(source_string,"<string>","exec",_ast.PyCF_ONLY_AST)
the body of the ast object will have two elements, an import object, and a expr object. However, I'd like to go further, and obtain the AST of import and listdir, in other words, I'd like to make _ast descend to the lowest level possible.
I think it's logical that this sort of thing should be possible. The question is how?
EDIT: by the lowest level possible, I didn't mean accesing what's "visible". I'd like to get the AST for the implementation of listdir as well: like stat and other function calls that may be executed for it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您确实可以通过这种方式获得整个树 - 一直到底部 - 但是,它是作为一棵树保存的,确切地说......所以在每个级别,为了获得子级,您必须显式访问所需的属性。 例如(我将
compile
结果命名为cf
而不是ast
因为这会隐藏标准库 ast 模块 - 我假设你只有 2.5 而不是 2.6,这就是为什么您使用较低级别的_ast
模块?)...:这就是告诉您 import 语句正在导入 name
os< /code> (这只是因为 1 是
.body[0]
的.names
字段的长度,即import
) 。在 Python 2.6 的模块
ast
中,您还可以获得帮助程序,让您在树上更轻松地导航(例如通过Visitor
设计模式)——但整个树都在那里在 2.5(使用_ast
)或 2.5(使用ast
)中,并且在任何一种情况下都以完全相同的方式表示。要方便地访问树中的所有节点,在 2.6 中,请使用模块 ast(无前导下划线)并根据需要子类
ast.NodeVisitor
(或等效地递归地使用ast.iter_child_nodes
和ast.iter_fields
根据需要)。 当然,如果您由于某种原因陷入 2.5 版本,这些助手可以在_ast
之上用纯 Python 实现。You do get the whole tree this way -- all the way to the bottom -- but, it IS held as a tree, exactly... so at each level to get the children you have to explicitly visit the needed attributes. For example (i'm naming the
compile
resultcf
rather thanast
because that would hide the standard library ast module -- I assume you only have 2.5 rather than 2.6, which is why you're using the lower-level_ast
module instead?)...:This is what tells you that the import statement is importing name
os
(and that one only because 1 is the lengths of the.names
field of.body[0]
which is theimport
).In Python 2.6's module
ast
you also get helpers to let you navigate more easily on a tree (e.g. by theVisitor
design pattern) -- but the whole tree is there in either 2.5 (with_ast
) or 2.5 (withast
), and in either case is represented in exactly the same way.To handily visit all the nodes in the tree, in 2.6, use module ast (no leading underscore) and subclass
ast.NodeVisitor
as appropriate (or equivalently useast.iter_child_nodes
recursively andast.iter_fields
as needed). Of course these helpers can be implemented in pure Python on top of_ast
if you're stuck in 2.5 for some reason.华泰
HTH