如何在Python中获取调用者的文件名和方法名

55
例如,a.boo 方法调用 b.foo 方法。在 b.foo 方法中,我该如何获取 a 的文件名(我不想将 __file__ 传递给 b.foo 方法)...

谢谢您的回答,我发现这里对我来说是最好的:https://dev59.com/mXA65IYBdhLWcg3wogOe - Zhenyu Li
7个回答

66
您可以使用inspect模块来实现此功能:
frame = inspect.stack()[1]
module = inspect.getmodule(frame[0])
filename = module.__file__

5
inspect.getmodule()在某些情况下会返回None,因此更加可靠的方法是: filename = frame[0].f_code.co_filename - dux2
3
为什么不直接使用filename = frame[1](或在Python 3.5+中使用frame.filename)? - Aran-Fey

38

Python 3.5+

一行代码解决

要获取完整的文件名(包括路径和扩展名),在被调用者中使用:

import inspect
filename = inspect.stack()[1].filename 

完整文件名与仅文件名

使用inspect.stack()来检索调用者的文件名。另外,以下代码也会剪切掉完整文件名开头的路径和结尾的文件扩展名:

# 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

然后可以这样使用:

# 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

官方文档


19
受ThiefMaster答案启发,但即使inspect.getmodule()返回None也可用:
frame = inspect.stack()[1]
filename = frame[0].f_code.co_filename

7
这可以使用inspect模块来完成,具体来说是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

演示:
import b

print(b.get_caller_filepath())
# output: D:\Users\Aran-Fey\a.py

4
您可以使用 traceback 模块:
import traceback

你可以像这样打印回溯信息:

print traceback.format_stack()

我已经很久没有使用过这个了,但这应该足以让你开始。


1
阅读所有这些解决方案,似乎这个也可以起作用?
import inspect
print inspect.stack()[1][1]

在该框架中的第二项已经是调用者的文件名,这是否足够健壮?

2
当然,它很强大,但不太易读。因此,inspect.stack()[1].filename是首选语法,支持Python 3.5及以上版本。 - Stefan

1

之前的解决方案有问题(因为某些原因返回了“<string>”)。这是我的解决方案:

traceback.format_stack()[0].split('"')[1]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接