Python AST 处理

7 投票
1 回答
3868 浏览
提问于 2025-04-15 20:00

我有一个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难”)。

但是,如果你只需要解决简单的“直接调用”情况,那就没问题了;-)。

撰写回答