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__
to b.foo
method)...
-
thanks for your answer, and I found here is the best for me now: http://stackoverflow.com/questions/3711184/how-to-use-inspect-to-get-the-callers-info-from-callee – Zhenyu Li Dec 04 '12 at 09:19
7 Answers
You can use the inspect
module to achieve this:
frame = inspect.stack()[1]
module = inspect.getmodule(frame[0])
filename = module.__file__

- 5,247
- 4
- 30
- 63

- 310,957
- 84
- 592
- 636
-
4`inspect.getmodule()` may return `None` under some conditions, so a more bulletproof way is: ```filename = frame[0].f_code.co_filename``` – dux2 Sep 06 '18 at 09:50
-
3Why not just `filename = frame[1]` (or `frame.filename` in python 3.5+)? – Aran-Fey Apr 02 '19 at 08:16
Python 3.5+
One-liner
To get the full filename (with path and file extension), use in the callee:
import inspect
filename = inspect.stack()[1].filename
Full filename vs filename only
To retrieve the caller's filename use inspect.stack(). Additionally, the following code also trims the path at the beginning and the file extension at the end of the full filename:
# Callee.py
import inspect
import os.path
def get_caller_info():
# first get the full filename (including path and file extension)
caller_frame = inspect.stack()[1]
caller_filename_full = caller_frame.filename
# now get rid of the directory (via basename)
# then split filename and extension (via splitext)
caller_filename_only = os.path.splitext(os.path.basename(caller_filename_full))[0]
# return both filename versions as tuple
return caller_filename_full, caller_filename_only
It can then be used like so:
# Caller.py
import callee
filename_full, filename_only = callee.get_caller_info()
print(f"> Filename full: {filename_full}")
print(f"> Filename only: {filename_only}")
# Output
# > Filename full: /workspaces/python/caller_filename/caller.py
# > Filename only: caller
Official docs
- os.path.basename(): to remove the path from the filename (still includes the extension)
- os.path.splitext(): to split the the filename and the file extension

- 13,026
- 8
- 71
- 88
Inspired by ThiefMaster's answer but works also if inspect.getmodule()
returns None
:
frame = inspect.stack()[1]
filename = frame[0].f_code.co_filename

- 1,770
- 1
- 21
- 27
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

- 39,665
- 11
- 104
- 149
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.

- 36,443
- 4
- 48
- 76

- 122,701
- 101
- 260
- 319
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?

- 412
- 6
- 14
-
2Sure it is robust, it is just not very readable. Therefore, `inspect.stack()[1].filename` is the preferred syntax which is supported as of Python 3.5. – Stefan Mar 17 '21 at 12:49
Had problems with solutions above (returned '<string>' for some reason). This is mine:
traceback.format_stack()[0].split('"')[1]

- 97
- 4