使用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()(ast.NodeVisitor子类)打印<ast.Try object at 0xXXX>,但如果我在Visitor类中添加visit_FunctionDef方法:

密码 with 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

Expected 输出

my_add
<ast.Try object at 0xXXX>

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

我判断了一下,visit_Try方法似乎还可以,因为它似乎尊重我在这里读到的内容:class ast.NodeVisitor.visit.它也没有遭到反对.

我不理解这种行为.如何获得所需的输出?

Python3.9和3.10中的行为相同.

推荐答案

您需要向.generic_visit()添加一个调用,以便访问功能 node 的子 node .默认情况下,不会访问 node 的子 node .

所以,你的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>

Python相关问答推荐

Pydantic:如何将对象列表表示为dict(将列表序列化为dict)

使用pandas、matplotlib和Yearbox绘制时显示错误的年份

如何在BeautifulSoup中链接Find()方法并处理无?

在内部列表上滚动窗口

替换字符串中的多个重叠子字符串

SQLGory-file包FilField不允许提供自定义文件名,自动将文件保存为未命名

删除最后一个pip安装的包

如何访问所有文件,例如环境变量

使用groupby Pandas的一些操作

pyscript中的压痕问题

如何将一个动态分配的C数组转换为Numpy数组,并在C扩展模块中返回给Python

梯度下降:简化要素集的运行时间比原始要素集长

利用Selenium和Beautiful Soup实现Web抓取JavaScript表

如何在UserSerializer中添加显式字段?

如何保持服务器发送的事件连接活动?

将pandas导出到CSV数据,但在此之前,将日期按最小到最大排序

人口全部乱序 - Python—Matplotlib—映射

如何在一组行中找到循环?

上传文件并使用Panda打开时的Flask 问题

为什么按下按钮后屏幕的 colored颜色 保持不变?