当前位置: 首页 > 面试题库 >

如何使用ast.NodeVisitor的简单示例?

谢雅珺
2023-03-14
问题内容

有没有人有一个使用ast.NodeVisitor的简单示例来遍历Python
2.6中的抽象语法树?对我来说,visit和generic_visit之间的区别尚不清楚,我无法使用Google
Codesearch或纯Google找到任何示例。


问题答案:

ast.visit-当然,除非您在子类中覆盖了它-
当被调用以访问ast.Nodeclass的时fooself.visit_foo如果存在该方法,则调用,否则self.generic_visit。后者再次在类ast本身的实现中,仅self.visit在每个子节点上调用(并且不执行其他任何操作)。

因此,请考虑例如:

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

在这里,我们不仅要generic_visit打印类名,而且 还要 调用基类(以便也可以访问所有子类)。例如:

>>> x = v()
>>> t = ast.parse('d[x] += v[y, x]')
>>> x.visit(t)

发出:

Module
AugAssign
Subscript
Name
Load
Index
Name
Load
Store
Add
Subscript
Name
Load
Index
Tuple
Name
Load
Name
Load
Load
Load

但是,假设我们不在乎Load节点(及其子节点-如果有的话;-)。那么一个简单的处理方法可能是:

>>> class w(v):
...   def visit_Load(self, node): pass
...

现在,当我们访问一个Load节点时,不再visitgeneric_visit其他节点调度,而是向我们的新visit_Load…调度,这根本不执行任何操作。所以:

>>> y = w()
>>> y.visit(t)
Module
AugAssign
Subscript
Name
Index
Name
Store
Add
Subscript
Name
Index
Tuple
Name
Name

或者,假设我们还想查看Name节点的实际名称;然后…:

>>> class z(v):
...   def visit_Name(self, node): print 'Name:', node.id
... 
>>> z().visit(t)
Module
AugAssign
Subscript
Name: d
Index
Name: x
Store
Add
Subscript
Name: v
Index
Tuple
Name: y
Name: x
Load
Load

但是,NodeVisitor是一个类,因为它使它可以在访问期间存储信息。假设我们想要的只是“模块”中的一组名称。然后我们就不需要重写generic_visit了,而是…:

>>> class allnames(ast.NodeVisitor):
...   def visit_Module(self, node):
...     self.names = set()
...     self.generic_visit(node)
...     print sorted(self.names)
...   def visit_Name(self, node):
...     self.names.add(node.id)
... 
>>> allnames().visit(t)
['d', 'v', 'x', 'y']

这种事情是一个比较典型的使用情况不是要求的覆盖那些generic_visit-通常情况下,你只在几个不同的节点有兴趣,像我们这里的模块和名称,所以我们就可以覆盖visit_Modulevisit_Name让AST的visit做代表我们派遣。



 类似资料:
  • 问题内容: 我不知道和 方法的作用,因此请举一个简单的示例帮助我。 问题答案: 这是一个非常简单的Python示例,应该补充pickle docs 。

  • 本文向大家介绍vue 递归组件的简单使用示例,包括了vue 递归组件的简单使用示例的使用技巧和注意事项,需要的朋友参考一下 前言 递归 相信很多同学已经不陌生了,算法中我们经常用递归来解决问题。比如经典的:从一个全为数字的数组中找出其中相加能等于目标数的组合。思路也不难,循环数组取值,不断递归相加,直到满足目标数条件。递归虽然能解决大部分,但弊处在于,很容易写出死循环的代码,导致爆栈。下面以我实际

  • 我只是跟随akka样本,但不能运行程序。 我已经使用自制程序(OSX Mountail Lion)安装了akka、sbt(0.13)、scala(2.10.3) 创建名为AKKA_TEST的空目录 创建build.sbt和hello.scala文件 在akka_test目录中运行sbt,编译命令运行良好 SBT的run命令抱怨没有检测到主类

  • 本文向大家介绍Docker教程:使用容器(简单示例),包括了Docker教程:使用容器(简单示例)的使用技巧和注意事项,需要的朋友参考一下 如果你是Docker的新手,看一下你应该学习的一些基础命令,以便开始管理容器。 Docker对软件开发生命周期产生了巨大影响,使得大规模软件部署变得简单而且安全。这个教程将介绍运行、启动、停止和删除Docker容器的基础知识。 Docker使得在不同的操作系统

  • 本文向大家介绍yii2简单使用less代替css示例,包括了yii2简单使用less代替css示例的使用技巧和注意事项,需要的朋友参考一下 添加组件php composer.phar require --prefer-dist singrana/yii2-less "*" 修改配置文件`main.php' 在AppAsset中 这样就可以用less来写样式了 以上就是本文的全部内容,希望对大家的学

  • 问题内容: 我有以下代码 在我创建自己的网站的过程中效果很好,没有JS,这些选项卡充当指向相关部分的跳转链接。当放置在定制的CMS中时,跳转链接不起作用时,我将不得不使用。我尝试将更多相对链接添加到选项卡,这使其无法使用JS,但使用JS时,选项卡式内容不会显示。 我想念什么吗? HTML: jQuery: 问题答案: 我猜您的网站在href方面遇到了问题,我认为当用户单击href时,网站会自动消除