我喜欢 _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 以及可能为其执行的其他函数调用。答案 0 :(得分:8)
你确实以这种方式获得整棵树 - 一直到底部 - 但是,它被保存为一棵树,确切地说......所以在每个级别都要让孩子们必须明确地访问所需的属性。例如(我命名compile
结果cf
而不是ast
,因为这会隐藏标准库ast模块 - 我假设你只有2.5而不是2.6,这就是为什么您正在使用较低级别的_ast
模块吗?)...:
>>> cf.body[0].names[0].name
'os'
这就是告诉你导入语句导入名称os
(而这只是因为1是.names
.body[0]
字段的长度{{1} }})。
在Python 2.6的模块import
中,您还可以获得帮助,以便您更轻松地在树上导航(例如,通过ast
设计模式) - 但是整个树都在2.5中(使用Visitor
)或2.5(使用_ast
),并且在任何一种情况下都以完全相同的方式表示。
为了方便地访问树中的所有节点,在2.6中,根据需要使用模块ast(无前导下划线)和子类ast
(或者等效地使用递归ast.NodeVisitor
和ast.iter_child_nodes
作为需要)。当然,如果由于某种原因你被困在2.5中,这些助手可以在ast.iter_fields
之上用纯Python实现。
答案 1 :(得分:5)
py> ast._fields
('body',)
py> ast.body
[<_ast.Import object at 0xb7978e8c>, <_ast.Expr object at 0xb7978f0c>]
py> ast.body[1]
<_ast.Expr object at 0xb7978f0c>
py> ast.body[1]._fields
('value',)
py> ast.body[1].value
<_ast.Call object at 0xb7978f2c>
py> ast.body[1].value._fields
('func', 'args', 'keywords', 'starargs', 'kwargs')
py> ast.body[1].value.args
[<_ast.Str object at 0xb7978fac>]
py> ast.body[1].value.args[0]
<_ast.Str object at 0xb7978fac>
py> ast.body[1].value.args[0]._fields
('s',)
py> ast.body[1].value.args[0].s
'.'
HTH