for example, a.boo
method calls b.foo
method. In b.foo
method, how can I get a\'s file name (I don\'t want to pass __file__
This can be done with the inspect module, specifically inspect.stack:
import inspect
import os.path
def get_caller_filepath():
# get the caller's stack frame and extract its file path
frame_info = inspect.stack()[1]
filepath = frame_info[1] # in python 3.5+, you can use frame_info.filename
del frame_info # drop the reference to the stack frame to avoid reference cycles
# make the path absolute (optional)
filepath = os.path.abspath(filepath)
return filepath
Demonstration:
import b
print(b.get_caller_filepath())
# output: D:\Users\Aran-Fey\a.py
Reading all these solutions, it seems like this works as well?
import inspect
print inspect.stack()[1][1]
The second item in the frame already is the file name of the caller, or is this not robust?
You can use the inspect
module to achieve this:
frame = inspect.stack()[1]
module = inspect.getmodule(frame[0])
filename = module.__file__
To retrieve just the caller's filename with no path at the beginning or extension at the end, use:
import inspect
import os
# First get the full filename (including path and file extension)
caller_frame = inspect.stack()[1]
caller_filename = caller_frame.filename
# Now get rid of the directory and extension
filename = os.path.splitext(os.path.basename(caller_filename))[0]
# Output
print(f"Caller Filename: {caller_filename}")
print(f"Filename: {filename}")
Sources:
Inspired by ThiefMaster's answer but works also if inspect.getmodule()
returns None
:
frame = inspect.stack()[1]
filename = frame[0].f_code.co_filename
you can use the traceback
module:
import traceback
and you can print the back trace like this:
print traceback.format_stack()
I haven't used this in years, but this should be enough to get you started.