Python AST 处理
我有一个Python的抽象语法树(AST),这是通过ast.parse()得到的。
我知道这是一个类方法的AST。
我该如何找到这个类中所有调用其他方法的地方呢?
简单来说,我想收集类似这样的内容:
['foo', 'bar']
对于像下面这样的代码片段:
def baz(self): # this is a class method
'''baz docstring'''
self.foo() + self.bar()
我需要一个函数,这个函数可以接受一个AST,并返回在同一个类的方法中被调用的其他方法的列表(方法名以字符串形式表示)。
1 个回答
18
一般来说,我们的做法是创建一个新的类,继承自 ast.NodeVisitor
:
>>> class VisitCalls(ast.NodeVisitor):
... def visit_Call(self, what):
... if what.func.value.id == 'self':
... print what.func.attr
...
>>> f='''def x(self):
... return self.bar() + self.baz()
... '''
>>> xx = ast.parse(f)
>>> VisitCalls().visit(xx)
bar
baz
不过,这样做只能捕捉到直接对 self.something
的调用。在更复杂的情况下,比如你可能会有 somelist.append(self.blah)
,然后在代码的后面某个地方又有 somelist[i + j]()
:要判断后者是否是对 self.blah
的调用,还是对其他与当前实例的方法无关的可调用对象的调用,这个问题是非常复杂的(计算机科学里说这是“图灵完备”,意思是说在一般情况下是完全无法解决的,类似于数学家说的“NP难”)。
但是,如果你只需要解决简单的“直接调用”情况,那就没问题了;-)。