简体   繁体   中英

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

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

You can use the inspect module to achieve this:

frame = inspect.stack()[1]
module = inspect.getmodule(frame[0])
filename = module.__file__

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

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

frame = inspect.stack()[1]
filename = frame[0].f_code.co_filename

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

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.

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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM