Python-AST:如何获得nod的子节点

2024-10-05 13:21:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在研究python2.6.5。在

给定一个抽象语法树,我想获得它的子级。在

我搜索堆栈溢出,但没有结果。大多数帖子都是关于ast.NodeVisitor和其中定义的方法visit,generic_visit()。 然而,AFAIU、visit()和{}并没有给我们孩子,而是直接递归地将函数应用到他们身上

有人能写一个简短的代码来演示一下吗? 在python库中是否有一个预定义的函数?在

谢谢!在


Tags: 方法函数代码定义堆栈语法孩子visit
2条回答

包含节点子节点的附件取决于节点所表示的语法类型。每个节点类也有一个特殊的_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

考虑:

^{pr2}$

实际上,如果你看一下语法,第一个产生式规则是针对模块的。它似乎需要一系列语句,作为一个名为body的参数。在

>>> ast.parse('5+a')._fields
('body',)
>>> ast.parse('5+a').body
[<_ast.Expr object at 0x02E965B0>]

AST的_fields属性只是“body”,body属性是一系列AST节点。回到语法,在stmt的产生式规则中,我们看到Expr使用一个名为value的表达式

>>> ast.parse('5+a').body[0].value
<_ast.BinOp object at 0x02E96330>

如果我们查找BinOp的定义,我们会发现它有3个不同的参数,left、op和right。我希望你能从那里开始。在

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                                                 

                                                                               `

相关问题 更多 >

    热门问题