向 AST 访问者添加访问函数可防止触发其他方法

Adding visit function to AST visitor prevents other methods from firing

使用ast module,我运行遇到了一个奇怪的问题:

代码

import ast
from _ast import Try

code = """
def my_add(a, b):
    try:
        return a + b
    except TypeError:
        return a + b
"""

class Visitor(ast.NodeVisitor):
    def visit_Try(self, node: Try):
        print(node)
        return node


Visitor().visit(ast.parse(code))

输出

<ast.Try object at 0xXXX>

在这里,Visitor().visit() (a ast.NodeVisitor subclass) 打印 <ast.Try object at 0xXXX>,但是如果我将 visit_FunctionDef 方法添加到 Visitor class:

代码 visit_FunctionDef

import ast
from _ast import Try

code = """
def my_add(a, b):
    try:
        return a + b
    except TypeError:
        return a + b
"""

class Visitor(ast.NodeVisitor):
    def visit_Try(self, node: Try):
        print(node)
        return node

    def visit_FunctionDef(self, node: ast.FunctionDef):
        print(node.name)
        return node

Visitor().visit(ast.parse(code))

输出

my_add

预期输出

my_add
<ast.Try object at 0xXXX>

现在唯一打印的行是 my_add,我希望有两行,my_add,然后是 <ast.Try object at 0xXXX>

我检查了一下 visit_Try 方法似乎没问题,因为它似乎尊重我在这里可以阅读的内容:class ast.NodeVisitor.visit。它也没有被弃用。

我不明白这种行为。如何获得所需的输出?

在 Python 3.9 和 3.10 中的行为相同。

您需要添加对.generic_visit()的调用,以便访问函数节点的子节点。默认情况下不访问节点的子节点。

因此,您的 visit_FunctionDef 应该如下所示:

def visit_FunctionDef(self, node: ast.FunctionDef):
    print(node.name)
    self.generic_visit(node)
    return node

这输出:

my_add
<_ast.Try object at 0x7fbce58dd250>