如何使用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
覆盖堆栈帧:
例如pysourceinfo.PySourceInfo.getCallerLinenumber(spos=1)
spos=0
是库函数,spos=1
是调用者,spos=2
是调用者的调用者,等等。
【讨论】:
【参考方案4】:如果调用者是主文件,只需使用 sys.argv[0]
【讨论】:
以上是关于如何使用inspect从Python中的被调用者那里获取调用者的信息?的主要内容,如果未能解决你的问题,请参考以下文章
null 传递给在 Xcode 7 中需要非 null 参数的被调用者