jmu*_*sch 47 python sys inspect traceback
在什么情况下我想用一个而不是另一个?
有什么区别:
>>> import inspect
>>> print(inspect.getouterframes(inspect.currentframe()))
[(<frame object at 0x8fc262c>, '<stdin>', 1, '<module>', None, None)]
Run Code Online (Sandbox Code Playgroud)
和:
>>> import traceback
>>> traceback.extract_stack()
[('<stdin>', 1, '<module>', None)]
Run Code Online (Sandbox Code Playgroud)
更新:
另一个:
>>> import sys
>>> print(sys._getframe().f_trace,sys._getframe().f_code)
(None, <code object <module> at 0x8682a88, file "<stdin>", line 1>)
Run Code Online (Sandbox Code Playgroud)
我不明白这里的细微差别:
更新2,问题问题后的一段时间,但非常相关
roi*_*ppi 52
好吧,因为这似乎更多的是关于堆栈帧/调用堆栈的一般情况,让我们来看看:
def f():
try:
g()
except:
# WE WILL DO THINGS HERE
def g():
h()
def h():
raise Exception('stuff')
#CALL
f()
Run Code Online (Sandbox Code Playgroud)
当我们进入时h()
,调用堆栈上有4个帧.
[top level]
[f()]
[g()]
[h()] #<-- we're here
Run Code Online (Sandbox Code Playgroud)
(如果我们试图sys.getrecursionlimit()
在堆栈上放置多个帧,我们会得到一个RuntimeError
,这是python的版本StackOverflow
;-))
"外部"指的是调用堆栈中我们上面的所有内容(字面意思是:"向上"方向).所以为了,g
话f
,那么顶部(模块)的水平.同样,"内"是指一切向下调用堆栈.如果我们捕获一个异常f()
,那个traceback对象将引用所有被解开的内部堆栈帧以使我们到达那一点.
def f():
try:
g()
except:
import inspect
import sys
#the third(last) item in sys.exc_info() is the current traceback object
return inspect.getinnerframes(sys.exc_info()[-1])
Run Code Online (Sandbox Code Playgroud)
这给出了:
[(<frame object at 0xaad758>, 'test.py', 3, 'f', [' g()\n'], 0),
(<frame object at 0x7f5edeb23648>, 'test.py', 10, 'g', [' h()\n'], 0),
(<frame object at 0x7f5edeabdc50>, 'test.py', 13, 'h', [" raise Exception('stuff')\n"], 0)]
Run Code Online (Sandbox Code Playgroud)
正如所料,三个内框架f,g和h.现在,我们可以采取的最后一帧的对象(一个来自h()
),并要求其外部框架:
[(<frame object at 0x7f6e996e6a48>, 'test.py', 13, 'h', [" raise Exception('stuff')\n"], 0),
(<frame object at 0x1bf58b8>, 'test.py', 10, 'g', [' h()\n'], 0),
(<frame object at 0x7f6e99620240>, 'test.py', 7, 'f', [' return inspect.getinnerframes(sys.exc_info()[-1])\n'], 0),
(<frame object at 0x7f6e99725438>, 'test.py', 23, '<module>', ['print(inspect.getouterframes(f()[-1][0]))\n'], 0)]
Run Code Online (Sandbox Code Playgroud)
所以,你去了,就是这样:我们只是在导航调用堆栈.为了比较,这是traceback.extract_stack(f()[-1][0])
给出的:
[('test.py', 23, '<module>', 'print(traceback.extract_stack(f()[-1][0]))'),
('test.py', 7, 'f', 'return inspect.getinnerframes(sys.exc_info()[-1])'),
('test.py', 10, 'g', 'h()'),
('test.py', 13, 'h', "raise Exception('stuff')")]
Run Code Online (Sandbox Code Playgroud)
注意这里的反转顺序与getouterframes
减少的输出相比较.事实上,如果你眯着眼睛,这基本上看起来像一个普通的回溯(哎,这就是,只有一点点更多的格式).
总结:既inspect.getouterframes
和traceback.extract_stack
包含的所有信息复制你在你的日常回溯一般见到的; extract_stack
只是删除对堆栈帧的引用,因为一旦你从一个给定的帧向外格式化堆栈跟踪,它就不再需要它们了.
Bre*_*arn 10
该文档的inspect
模块,说:
当以下函数返回"帧记录"时,每个记录是六个项目的元组:框架对象,文件名,当前行的行号,函数名称,源代码中的上下文行列表,以及该列表中当前行的索引.
该文档的traceback
模块,说:
"预处理"堆栈跟踪条目是4元组(文件名,行号,函数名,文本)
因此,不同的是,帧记录还包括框对象和背景的一些线,而回溯只包括各行的在调用堆栈中的文本(即,导致调用extract_stack
呼叫).
traceback
如果您只想打印回溯,可以使用堆栈.如文档所示,这是为了向用户显示而处理的信息.inspect
如果您想要实际对调用堆栈执行任何操作(例如,从调用帧读取变量),则需要访问框架对象.
归档时间: |
|
查看次数: |
12224 次 |
最近记录: |