¿Cómo obtener la ruta del archivo de un módulo desde una función ejecutada pero no declarada en Python?

Si quiero la ruta del módulo actual, __file__ .

Ahora digamos que quiero una función para devolver eso. No puedo hacer

 def get_path(): return __file__ 

Debido a que devolverá la ruta del módulo en el que se ha declarado la función.

Necesito que funcione, incluso si la función no se llama desde la raíz del módulo sino a cualquier nivel de anidamiento.

Así es como lo haría:

 import sys def get_path(): namespace = sys._getframe(1).f_globals # caller's globals return namespace.get('__file__') 

Consíguelo en el globals global en ese caso:

 def get_path(): return globals()['__file__'] 

Editar en respuesta al comentario: dados los siguientes archivos:

 # a.py def get_path(): return 'Path from a.py: ' + globals()['__file__'] # b.py import a def get_path(): return 'Path from b.py: ' + globals()['__file__'] print get_path() print a.get_path() 

Ejecutar esto me dará el siguiente resultado:

 C:\workspace>python b.py Path from b.py: b.py Path from a.py: C:\workspace\a.py 

Junto a los caminos absolutos / relativos que son diferentes (por brevedad, dejémoslo así), me parece bien.

Encontré una manera de hacerlo con el módulo de inspección. Estoy de acuerdo con esta solución, pero si alguien encuentra la manera de hacerlo sin deshacerse de todo el stacktrace, sería más limpio y aceptaría su respuesta con gratitud:

 def get_path(): frame, filename, line_number, function_name, lines, index =\ inspect.getouterframes(inspect.currentframe())[1] return filename