how to get the caller's filename, method name in python

Question:

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)…

Asked By: Zhenyu Li

||

Answers:

You can use the inspect module to achieve this:

frame = inspect.stack()[1]
module = inspect.getmodule(frame[0])
filename = module.__file__
Answered By: ThiefMaster

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.

Answered By: Nathan Fellman

Inspired by ThiefMaster’s answer but works also if inspect.getmodule() returns None:

frame = inspect.stack()[1]
filename = frame[0].f_code.co_filename
Answered By: dux2

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?

Answered By: the pillow

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:UsersAran-Feya.py
Answered By: Aran-Fey

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

Answered By: winklerrr
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.