2011-02-09 96 views
9

我正在玩python ast(抽象語法樹)。使用Python ast模塊在語法樹中訪問節點

我寫了下面的內容,它訪問了AST的所有節點。

import ast 

class Py2Neko(ast.NodeVisitor): 
    def generic_visit(self, node): 
       print type(node).__name__ 
       ast.NodeVisitor.generic_visit(self, node) 

     def visit_Name(self, node): 
       print 'Name :', node.id 

     def visit_Num(self, node): 
       print 'Num :', node.__dict__['n'] 

     def visit_Str(self, node): 
       print "Str :", node.s 

if __name__ == '__main__': 

    node = ast.parse("a = 1 + 2") 

    print ast.dump(node) 

    v = Py2Neko() 
    v.visit(node) 

然後增加了一些方法來Py2Neko類

def visit_Print(self, node): 
    print "Print :" 

def visit_Assign(self, node): 
    print "Assign :" 

def visit_Expr(self, node): 
    print "Expr :" 

但是當它遇到一個「打印」語句或assignement或表達它似乎停止,並沒有進一步的打算。

它輸出:

Module(body=[Assign(targets=[Name(id='a', ctx=Store())], value=BinOp(left=Num(n=1), op=Add(),  right=Num(n=2)))]) 
Module 
Assign : 

誰能告訴我我做錯了什麼。

我使用Python 2.6.6

回答

10

由於您的visit_Assign方法沒有顯式處理Assign節點的子節點,所以語法樹的遍歷在那裏停止。

如果您查看ast.py實現中的NodeVisitor.generic_visit方法,您會看到它循環遍歷當前節點的子節點。所以,你可以顯式調用從您的每一個方法需要處理孩子的基類generic_visit方法:

import ast 

class Py2Neko(ast.NodeVisitor): 
    def generic_visit(self, node): 
     print type(node).__name__ 
     ast.NodeVisitor.generic_visit(self, node) 

    def visit_Name(self, node): 
     print 'Name :', node.id 

    def visit_Num(self, node): 
     print 'Num :', node.__dict__['n'] 

    def visit_Str(self, node): 
     print "Str :", node.s 

    def visit_Print(self, node): 
     print "Print :" 
     ast.NodeVisitor.generic_visit(self, node) 

    def visit_Assign(self, node): 
     print "Assign :" 
     ast.NodeVisitor.generic_visit(self, node) 

    def visit_Expr(self, node): 
     print "Expr :" 
     ast.NodeVisitor.generic_visit(self, node) 

if __name__ == '__main__': 
    node = ast.parse("a = 1 + 2") 

    print ast.dump(node) 

    v = Py2Neko() 
    v.visit(node) 
4

對於非終端節點,您的訪問功能有探望子女。有關更多信息,請參閱Simple example of how to use ast.NodeVisitor?

+0

D'哦 - 我想這一點,但不知何故(不合理)假設`NodeVisitor`處理這個在其自己的。 – delnan 2011-02-09 17:02:30

+0

我看到你提供的例子,但如何指定訪問孩子?例如這裏:http://dev.pocoo.org/hg/sandbox/file/98ce1ce17c7c/ast/codegen.py他們有visit_Print()和其他人,它似乎工作,但不適合我。 – narke 2011-02-09 17:15:45

相關問題