我正在使用Python 2.6.5。Python AST:如何獲得節點的子節點
給定一個抽象語法樹,我想獲取它的子元素。
我搜索堆棧溢出,但無濟於事。大部分帖子都在ast.NodeVisitor
以及其中定義的方法visit,generic_visit()
。 然而AFAIU,visit()
和generic_visit()
不給我們的孩子們,而他們直接遞歸應用的功能對他們
可有人請寫一個簡短的代碼或者這樣來證明呢? 在Python庫中是否存在相同的預定義函數?
謝謝!
我正在使用Python 2.6.5。Python AST:如何獲得節點的子節點
給定一個抽象語法樹,我想獲取它的子元素。
我搜索堆棧溢出,但無濟於事。大部分帖子都在ast.NodeVisitor
以及其中定義的方法visit,generic_visit()
。 然而AFAIU,visit()
和generic_visit()
不給我們的孩子們,而他們直接遞歸應用的功能對他們
可有人請寫一個簡短的代碼或者這樣來證明呢? 在Python庫中是否存在相同的預定義函數?
謝謝!
包含節點子節點的attaributes取決於節點表示的語法類型。每個節點類還有一個特殊的_fields
屬性,該屬性列出了該類所具有的子節點的屬性名稱。例如,
>>> ast.parse('5+a')
<_ast.Module object at 0x02C1F730>
>>> ast.parse('5+a').body
[<_ast.Expr object at 0x02C1FF50>]
>>> ast.parse('5+a').body[0]
<_ast.Expr object at 0x02C1FBF0>
>>> ast.parse('5+a').body[0]._fields
('value',)
>>> ast.parse('5+a').body[0].value
<_ast.BinOp object at 0x02C1FF90>
>>> ast.parse('5+a').body[0].value._fields
('left', 'op', 'right')
>>> ast.parse('5+a').body[0].value.left
<_ast.Num object at 0x02C1FB70>
等等。
編輯,澄清這是怎麼回事
想要進一步瞭解,請在CPython Abstract Grammar
一目瞭然考慮:
>>> type(ast.parse('5+a'))
<class '_ast.Module'>
事實上,如果你看一下語法,第一條生產規則是針對模塊。它似乎需要一系列的聲明,作爲一個稱爲body的參數。
>>> ast.parse('5+a')._fields
('body',)
>>> ast.parse('5+a').body
[<_ast.Expr object at 0x02E965B0>]
的AST的_fields
屬性僅僅是「體」,並且身體屬性是AST節點序列。回到語法,尋找在stmt
生產規則,我們看到Expr
接受一個EXPR,命名爲value
>>> ast.parse('5+a').body[0].value
<_ast.BinOp object at 0x02E96330>
如果我們仰望的BinOp的定義,我們可以看到,它需要3個不同的參數,左,操作和權利。我希望你應該能夠從那裏出發。
ast
模塊提供了一個iter_child_nodes
函數,您可能會發現它很有用。
def iter_child_nodes(node):
"""
Yield all direct child nodes of *node*, that is, all fields that are nodes
and all items of fields that are lists of nodes.
"""
for name, field in iter_fields(node):
if isinstance(field, AST):
yield field
elif isinstance(field, list):
for item in field:
if isinstance(item, AST):
yield item
`
感謝您的回覆!不過,我還沒有正確理解它......所以node._fields會給那個特定節點的孩子? (以tupple的形式?)....那麼身體和價值是什麼意思?謝謝你的幫助! – Adwaitvedant 2011-05-16 05:37:11