Introspección de Python: cómo verificar el módulo / línea de llamada actual desde dentro de la función

Tengo una función:

# utils.py def hello(name='World'): # Detect where I'm being called from. print('Hi, %s. You called this from %s at line # %d.' % (name, mod, lineno)) # ``mod`` and ``lineno`` on previous line would have been set in real use. 

Importo esa función y la ejecuto en otro lugar

 # other.py (this comment at line # 138) from utils import hello hello('Johnny') # From inside ``hello`` I want to be able to detect that this # was called from other.py at line # 140 

Acceda al marco de inspect.currentframe() de inspect.currentframe() :

 import inspect def hello(name='World'): f = inspect.currentframe().f_back mod = f.f_code.co_filename lineno = f.f_lineno print('Hi, %s. You called this from %s at line # %d.' % (name, mod, lineno)) 

El módulo de traceback permite extraer la stack, para que pueda ver cómo llegó al marco de stack actual. Si lo desea, puede extender esto para imprimir el llamante de la persona que llama, en la stack que desee:

 import traceback def _trace(): stack = traceback.extract_stack()[-3:-1] path, line, in_func, _instr = stack[0] print 'called from %s in func %s at line %s' % (path, in_func, line) def bar(): _trace() def foo(): bar() baz() def baz(): bar() bar() foo() 

Salida:

 called from hello.py in func  at line 20 called from hello.py in func foo at line 14 called from hello.py in func baz at line 18 

Utilice el módulo de warnings .

 import warnings def test(where): warnings.warn('hi from test', stacklevel=2) def foo(): test('inside foo') test('from main module') foo() 

Resultados:

 /tmp/test.py:9: UserWarning: hi from test test('from main module') /tmp/test.py:7: UserWarning: hi from test test('inside foo') 

Compruebe los números de línea. El uso del módulo de warnings es excelente porque el usuario de su módulo puede deshabilitar las advertencias o convertirlas en excepciones totalmente inspeccionables.