如何在Python中使用inspect从被呼叫者获取呼叫者的信息?


79

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

如何使用inspect获取那些信息?或者还有其他获取信息的方法吗?

import inspect

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

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

hello()

Answers:


98

呼叫者的帧比当前帧高一帧。您可以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)

7
@prosseek:要获取呼叫者的呼叫者,只需将索引更改[1][2]。(inspect.getouterframes返回帧列表...)。Python的组织精美。
unutbu

3
您还可以使用inspect.currentframe()。f_back。
yoyo

这似乎没有提供一种获取文件名完整路径的方法。
杰森·S

2
@JasonS:“堆栈框架中的文件名是相对于应用程序的启动目录而言的”。
unutbu

2
此代码示例有效,但性能很差。如果您只对单个帧感兴趣,而不对整个堆栈跟踪感兴趣,则可以获取前一个帧并检查它的帧信息: filename, line_number, clsname, lines, index = inspect.getframeinfo(sys._getframe(1))
Mouscellaneous

47

我建议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()

它比getouterframes@unutbu建议的使用效果好吗?
ixe013 2014年

8
它更紧凑,更好地反映了意图。
德米特里K. 2014年

请注意,getouterframes(currentframe())stack()等效于github.com/python/cpython/blob/master/Lib/inspect.py#L1442
ubershmekel,2016年

1
使用stack()很好的另一个原因是它显示了如何轻松获取其他帧。例如。您的hello()函数首先被另一个函数调用,您可以对其进行更新以返回两个级别。
查尔斯·普拉格


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.