2010-03-04 11 views
7

I eine Python AST haben [wie durch ast.parse zurückgegeben()].Python AST Verarbeitung

Ich weiß, dass dies ein AST einer Klassenmethode ist.

Wie finde ich alle Anrufe zu anderen Methoden der gleichen Klasse?

Grundsätzlich möchte ich etwas sammeln, wie:

['foo', 'bar'] 

für einen Code-Schnipsel wie:

def baz(self): # this is a class method 
    '''baz docstring''' 
    self.foo() + self.bar() 

Ich brauche eine Funktion, die ein AST und kehrt die Liste der anderen Methoden akzeptiert [Methodennamen als Strings] der Klasse, die innerhalb einer Methode derselben Klasse aufgerufen werden.

Antwort

16

Der allgemeine Ansatz ist ast.NodeVisitor Unterklasse:

>>> 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 

Dies ist jedoch nur „sofort“ ruft self.something fangen. Im allgemeinen Fall könnten Sie z.B. somelist.append(self.blah) und dann viel später im Code somelist[i + j](): das Problem der Bestimmung, ob der letztere ein Aufruf an self.blah oder zu einem anderen aufrufbar ist, die nichts mit Methoden der aktuellen Instanz zu tun hat, ist Turing-complete (CS-Jargon für „völlig unlöslich in der allgemeine Fall ", ähnlich wie ein Mathematiker" NP-schwer "sagen könnte ;-).

Aber wenn alles, was Sie brauchen, ist der einfachen „sofortiger Anruf“ Fall zu lösen, sie ist gut ;-) zu gehen.

+0

Vielen Dank für die Kommentare, die die Komplexität des allgemeinen Falles beschreiben. –