考虑以下代码:
#!python3
import warnings
import sys
def my_showwarning(*args, **kwargs):
frame = sys._getframe()
while frame is not None:
print('name:', frame.f_code.co_name, 'file:', frame.f_code.co_filename)
frame = frame.f_back
warnings.showwarning = my_showwarning
def foo():
bar()
def bar():
warnings.warn('Not good', UserWarning)
warnings.resetwarnings()
warnings.simplefilter('always')
foo()
输出结果为:
name: my_showwarning file: /home/nikratio/tmp/test.py
name: bar file: /home/nikratio/tmp/test.py
name: foo file: /home/nikratio/tmp/test.py
name: <module> file: /home/nikratio/tmp/test.py
为什么bar()
和my_showwarnings
之间没有堆叠框架?看一下CPython 3.4.4中的实现,warnings.warn
应该调用warnings.warn_explicit
,最后调用showwarning
- 所以在我看来应该(至少)有两个堆栈帧。 / p>
这是否与CPython默认使用C版本(_warnings
)有关? C扩展函数根本没有任何堆栈帧吗?