2011-12-01 12 views
5

Quiero obtener el número de línea de una función python en el código fuente. lo que tengo en tiempo de ejecución es el módulo, clase, método objetos¿Cómo obtener el número de línea de función (con/sin decorador) en un módulo de python?

echado un vistazo a inspeccionar

inspect.getsourcelines(object)  

que también da el número de línea en el resultado.

Veo que para los métodos con decoradores, la línea no. devuelto desde arriba inspecciona los puntos de función al código fuente del decorador real en lugar del código fuente de la función deseada. Entonces, ¿hay alguna manera de solucionar esto? (entiendo que el intérprete hace algo así como envolviendo la función dentro del decorador en tiempo de ejecución, pero podría estar equivocado)

Respuesta

4

No existe una solución fácil en el caso general.

Un decorador es una función que, dada una función, devuelve una función, normalmente envolviéndola en un cierre que realiza la operación para la que se diseñó el decorador.

Sin embargo, el archivo y la información del número de línea no se encuentran en el objeto de función y no se pueden "corregir" copiando esta información de la función envuelta al envoltorio. Esa información está en cambio contenida en el objeto code de la función (disponible con .func_code), y se comparte entre todos los cierres que va a crear.

>>> def bar(x): 
...  def foo(): 
...   return x 
...  return foo 
... 
>>> f1 = bar(1) 
>>> f2 = bar(2) 
>>> f1() 
1 
>>> f2() 
2 
>>> f1.func_code is f2.func_code 
True 
>>> 
+0

Ya veo, gracias por la explicación. Incluso con 'func_code' estoy obteniendo la línea no. del código fuente decorador. Procederé ignorando la configuración de la línea no. para métodos con cualquier decorador. Mi pregunta ahora es cómo encontrar un método que tenga _any_ decorator o no (nombre del decorador no conocido anteriormente) – Hari

+0

@Hari: un decorador puede devolver lo que quiera (incluso algo que no sea un cierre o incluso la misma función que éste) obtuve entrada, posiblemente haciendo algún otro cálculo antes de devolverlo), por lo que no hay un método 100% seguro para saber si una función ha sido decorada o no, dado el objeto de función. – 6502

1

El módulo wrapt resuelve este problema permitiendo que usted pueda escribir decoradores que preservan los metadatos necesarios para encontrar la fuente de una función, así como realizar otras introspección. Es como un mejorado functools.wraps.

Cuestiones relacionadas