2012-10-08 20 views
11

Una función de Python tiene un objeto de código __code__.Obtener la función de Python para un objeto de código

A sys.settrace traza frame tiene un objeto de código f_code.

Para aquellas llamadas al rastreador que son funciones, ¿cómo puedo obtener el objeto de función (y su miembro __annotation__)?

Hasta ahora, por ensayo y error, que tengo:

if hasattr(frame.f_globals.get(frame.f_code.co_name),"__annotations__"): 

Esto parece funcionar para las funciones, pero no para las funciones de la clase-miembros; peor aún, confunde funciones de miembros de clase con funciones de nivel superior del mismo nombre.

(. Estoy en Python 3.2.3 (Xubuntu) veo que Python 3.3 inspect módulo tiene una función signature; será este devolver la anotación para un objeto de código o lo hace también necesitan un objeto función?)

Respuesta

5

A través del módulo inspect.getframeinfo. Es decir, no hay una manera directa de hacerlo en Python. La mayoría de las veces puede obtener el objeto de código, sin tener la función ya, es a través de la inspección de cuadros.

La función getframeinfo de Inspect devuelve cierta información sobre el marco que se está ejecutando, luego puede recuperar el objeto de la función obteniendo su nombre.

Tough esto es dependiente de la implementación y tienen algunos inconvenientes:

>>> import inspect 
>>> def a(): 
... return inspect.currentframe() 
... 

>>> inspect.getframeinfo(a()) 
Traceback(filename='<stdin>', lineno=2, function='a', code_context=None, index=None) 
>>> b = inspect.getframeinfo(a()) 
>>> b.function 
'a' 

Otra forma, pero aún depende de la implementación, es utilizar el módulo GC (recolector de basura) para obtener los referentes a dicho objeto código.

>>> import gc 
>>> from types import FunctionType 
>>> def a(): pass 
... 
>>> code = a.__code__ 

>>> [obj for obj in gc.get_referrers(code) if isinstance(obj, FunctionType) ][0] 
<function a at 0x7f1ef4484500> 
>>> 

- Esto es para Python 3 - 2 para Python se debe reemplazar por __code__func_code

+0

campo '' function' la tupla de inspect.getframeinfo' parece que hay una cadena en lugar de un objeto función. ¿Y el enfoque de GC arriesga múltiples referencias? – Will

+0

Terminé usando gc.get_referrers (...) [0] – Will

+1

Puede agregar una marca para ver si func_code/__code__ es el objeto de código que desea para la lista de comprensión. Esto aún falla si genera múltiples funciones con cierres diferentes del mismo objeto de código, por ejemplo con un decorador Supongo que uno podría comparar los f_locals contra el conteo de celda del func_closure para cada ... –

Cuestiones relacionadas