¿Cómo usar inspeccionar para obtener la información de la persona que llama desde el destinatario en Python?

80

Necesito obtener la información de la persona que llama (qué archivo / qué línea) del destinatario. Aprendí que puedo usar el módulo inpect para eso, pero no exactamente cómo.

¿Cómo obtener esa información con inspeccionar? ¿O hay alguna otra forma de obtener la información?

import inspect

print __file__
c=inspect.currentframe()
print c.f_lineno

def hello():
    print inspect.stack
    ?? what file called me in what line?

hello()
prosseek
fuente

Respuestas:

99

El marco de la persona que llama es un marco más alto que el marco actual. Puede utilizar inspect.currentframe().f_backpara encontrar el marco de la persona que llama. Luego use inspect.getframeinfo para obtener el nombre de archivo y el número de línea de la persona que llama.

import inspect

def hello():
    previous_frame = inspect.currentframe().f_back
    (filename, line_number, 
     function_name, lines, index) = inspect.getframeinfo(previous_frame)
    return (filename, line_number, function_name, lines, index)

print(hello())

# ('/home/unutbu/pybin/test.py', 10, '<module>', ['hello()\n'], 0)
unutbu
fuente
7
@prosseek: para obtener la persona que llama, simplemente cambie el índice [1]a [2]. ( inspect.getouterframesdevuelve una lista de fotogramas ...). Python está muy bien organizado.
unutbu
3
También puede usar inspect.currentframe (). F_back.
yoyo
Esto no parece proporcionar una forma de obtener la ruta completa del nombre de archivo.
Jason S
2
@JasonS: "el nombre del archivo en el marco de la pila es relativo al directorio de inicio de la aplicación".
unutbu
4
Esta muestra de código funciona pero tiene un rendimiento bastante deficiente. Si sólo está interesado en un solo cuadro y no toda la traza de la pila, se puede obtener el cuadro anterior y compruebe que no la información del marco: filename, line_number, clsname, lines, index = inspect.getframeinfo(sys._getframe(1))
Mouscellaneous
47

Sugeriría usar inspect.stacken su lugar:

import inspect

def hello():
    frame,filename,line_number,function_name,lines,index = inspect.stack()[1]
    print(frame,filename,line_number,function_name,lines,index)
hello()
Dmitry K.
fuente
¿Cómo es mejor que usarlo getouterframescomo lo sugiere @unutbu?
ixe013
8
Es más compacto y refleja mejor la intención.
Dmitry K.
Tenga en cuenta que getouterframes(currentframe())y stack()son equivalentes bajo el capó github.com/python/cpython/blob/master/Lib/inspect.py#L1442
ubershmekel
1
Otra razón por la que usar stack () es bueno es que muestra cómo obtener fácilmente otros marcos. Si, por ejemplo. su función hello () es llamada por otra función primero, puede actualizarla para retroceder dos niveles.
Charles Plager
-5

Si la persona que llama es el archivo principal, simplemente use sys.argv [0]

Jacob Cohen
fuente