2010-03-04 17 views
7

Tengo un Python AST [tal como lo devuelve ast.parse()].Procesamiento Python AST

Sé que este es un AST de un método de clase.

¿Cómo puedo encontrar todas las llamadas a otros métodos de la misma clase?

Básicamente, quiero recoger algo como:

['foo', 'bar'] 

para un fragmento de código como:

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

Necesito una función que acepte un AST y devolverá la lista de otros métodos [nombres de métodos como cadenas] de la clase que se invoca dentro de un método de la misma clase.

Respuesta

16

El enfoque general es una subclase 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 

Sin embargo, esto sólo atrapar "inmediata" llamadas a self.something. En el caso general, podría tener, por ejemplo, somelist.append(self.blah) y luego mucho más tarde en el código somelist[i + j](): el problema de determinar si esta última es una llamada a self.blah o a algún otro invocable que no tiene nada que ver con los métodos de la instancia actual es Turing-complete (CS jerga para "completamente insoluble en el caso general ", al igual que un matemático podría decir" NP-hard ";-).

Pero si todo lo que necesita es resolver el simple caso de "llamada inmediata", ya está listo ;-).

+0

Muchas gracias por los comentarios que describen la complejidad del caso general. –