如何使用ast.NodeVisitor的简单示例?
有谁有一个使用 ast.NodeVisitor 来遍历 Python 2.6 中的抽象语法树的简单示例吗?我不清楚访问和 generic_visit 之间的区别,而且我找不到任何使用谷歌代码搜索或普通谷歌的示例。
Does anyone have a simple example using ast.NodeVisitor to walk the abstract syntax tree in Python 2.6? The difference between visit and generic_visit is unclear to me, and I cannot find any example using google codesearch or plain google.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
ast.visit
——当然,除非你在子类中重写它 ——当调用访问类foo
的ast.Node
时,如果该方法存在,则调用 self.visit_foo ,否则调用 self.generic_visit 。后者在类ast
本身的实现中,仅在每个子节点上调用self.visit
(并且不执行其他操作)。因此,请考虑,例如:
在这里,我们重写 generic_visit 来打印类名,但也调用基类(以便所有子类也将被调用)访问过)。例如...:
发出:
但是假设我们不关心负载节点(及其子节点——如果它们有的话;-)。那么处理这个问题的简单方法可能是,例如:
现在,当我们访问 Load 节点时,
visit
分派,不再是generic_visit
,而是分派到我们的新节点visit_Load
...它根本不执行任何操作。所以:或者,假设我们还想查看名称节点的实际名称; then...:
但是,NodeVisitor 是一个类,因为这可以让它在访问期间存储信息。假设我们想要的只是“模块”中的一组名称。那么我们就不再需要重写
generic_visit
了,而是......:与需要重写
generic_visit
的用例相比,这种事情是更典型的用例 --通常,您只对几种节点感兴趣,就像我们在 Module 和 Name 中一样,因此我们可以覆盖visit_Module
和visit_Name
并让 ast 的visit
代表我们进行调度。ast.visit
-- unless you override it in a subclass, of course -- when called to visit anast.Node
of classfoo
, callsself.visit_foo
if that method exists, otherwiseself.generic_visit
. The latter, again in its implementation in classast
itself, just callsself.visit
on every child node (and performs no other action).So, consider, for example:
Here, we're overriding
generic_visit
to print the class name, but also calling up to the base class (so that all children will also be visited). So for example...:emits:
But suppose we didn't care for Load nodes (and children thereof -- if they had any;-). Then a simple way to deal with that might be, e.g.:
Now when we're visiting a Load node,
visit
dispatches, NOT togeneric_visit
any more, but to our newvisit_Load
... which doesn't do anything at all. So:or, suppose we also wanted to see the actual names for Name nodes; then...:
But, NodeVisitor is a class because this lets it store information during a visit. Suppose all we want is the set of names in a "module". Then we don't need to override
generic_visit
any more, but rather...:This kind of thing is a more typical use case than ones requiring overrides of
generic_visit
-- normally, you're only interested in a few kinds of nodes, like we are here in Module and Name, so we can just overridevisit_Module
andvisit_Name
and let ast'svisit
do the dispatching on our behalf.查看 ast.py 中的代码并不难复制粘贴并滚动你自己的助行器。例如
打印出来
Looking at the code in ast.py it's not that hard to copy paste and roll your own walker. E.g.
Prints out
当找不到自定义访问者(即visit_Name)时,将调用
generic_visit
。这是我最近用 ast.NodeVisitor 编写的一段代码: https ://foss.heptapod.net/pypy/pypy/-/blob/80ead76ab428100ffeb01109c7fc0d94f1048af2/py/_code/_assertionnew.py 它解释 AST 节点以获取有关其中一些节点的调试信息,并使用generic_visit
当未提供特殊实现时。generic_visit
is called when a custom visitor (ie visit_Name) can't be found. Here's a piece of code I wrote recently with ast.NodeVisitor: https://foss.heptapod.net/pypy/pypy/-/blob/80ead76ab428100ffeb01109c7fc0d94f1048af2/py/_code/_assertionnew.py It interprets the AST nodes to gain debugging information about some of them and falls back in withgeneric_visit
when a special implementation isn't provided.