如何使用inspect从Python中的被调用者那里获取调用者的信息?

Posted

技术标签:

【中文标题】如何使用inspect从Python中的被调用者那里获取调用者的信息?【英文标题】:How to use inspect to get the caller's info from callee in Python? 【发布时间】:2011-04-12 06:57:26 【问题描述】:

我需要从被调用者那里获取调用者信息(什么文件/什么行)。我了解到我可以为此目的使用 inpect 模块,但不完全是。

如何通过检查获取这些信息?或者有没有其他方法可以获取信息?

import inspect

print __file__
c=inspect.currentframe()
print c.f_lineno

def hello():
    print inspect.stack
    ?? what file called me in what line?

hello()

【问题讨论】:

【参考方案1】:

调用者的帧比当前帧高一帧。您可以使用inspect.currentframe().f_back 来查找调用者的框架。 然后使用inspect.getframeinfo获取调用者的文件名和行号。

import inspect

def hello():
    previous_frame = inspect.currentframe().f_back
    (filename, line_number, 
     function_name, lines, index) = inspect.getframeinfo(previous_frame)
    return (filename, line_number, function_name, lines, index)

print(hello())

# ('/home/unutbu/pybin/test.py', 10, '<module>', ['hello()\n'], 0)

【讨论】:

@prosseek:要获取调用者的调用者,只需将索引[1] 更改为[2]。 (inspect.getouterframes 返回帧列表...)。 Python 组织精美。 你也可以使用inspect.currentframe().f_back。 这似乎没有提供获取文件名完整路径的方法。 @JasonS:“堆栈帧中的文件名是应用程序的relative to the start up directory”。 此代码示例有效,但性能很差。如果您只对单个帧而不是整个堆栈跟踪感兴趣,您可以获取前一帧并检查它的帧信息:filename, line_number, clsname, lines, index = inspect.getframeinfo(sys._getframe(1))【参考方案2】:

我建议改用inspect.stack

import inspect

def hello():
    frame,filename,line_number,function_name,lines,index = inspect.stack()[1]
    print(frame,filename,line_number,function_name,lines,index)
hello()

【讨论】:

按照@unutbu 的建议使用getouterframes 有什么好处? 更紧凑,更能体现意图。 请注意 getouterframes(currentframe())stack() 在底层是等效的 github.com/python/cpython/blob/master/Lib/inspect.py#L1442 使用 stack() 的另一个好处是它展示了如何轻松获取其他帧。如果,例如。您的 hello() 函数首先被另一个函数调用,您可以更新它以返回两个级别。【参考方案3】:

我发布了一个用于检查的包装器,它使用简单的堆栈帧寻址,通过单个参数 spos 覆盖堆栈帧:

https://pypi.python.org/pypi/pysourceinfo/ https://pythonhosted.org/pysourceinfo/

例如pysourceinfo.PySourceInfo.getCallerLinenumber(spos=1)

spos=0 是库函数,spos=1 是调用者,spos=2 是调用者的调用者,等等。

【讨论】:

【参考方案4】:

如果调用者是主文件,只需使用 sys.argv[0]

【讨论】:

以上是关于如何使用inspect从Python中的被调用者那里获取调用者的信息?的主要内容,如果未能解决你的问题,请参考以下文章

null 传递给在 Xcode 7 中需要非 null 参数的被调用者

如何将右值引用从调用者传递给被调用者

函数篇:Callback----回调函数

远程的jmeter自动执行完,如何回调通知被调用者“结束”状态

使用rpcgen时,调用者如何找到被调用者?

被调用者分配被调用者释放