【发布时间】:2014-07-13 22:40:02
【问题描述】:
在什么情况下我想使用一种而不是另一种?
有什么区别:
>>> import inspect
>>> print(inspect.getouterframes(inspect.currentframe()))
[(<frame object at 0x8fc262c>, '<stdin>', 1, '<module>', None, None)]
还有:
>>> import traceback
>>> traceback.extract_stack()
[('<stdin>', 1, '<module>', None)]
更新:
另一个:
>>> import sys
>>> print(sys._getframe().f_trace,sys._getframe().f_code)
(None, <code object <module> at 0x8682a88, file "<stdin>", line 1>)
我不明白这里的细微差别:
- 堆栈帧
- 框架对象
- 堆栈跟踪
更新 2,距离提出问题有一点时间,但非常相关
【问题讨论】:
-
@BrenBarn 这显然不是唯一的区别,因为
getouterframes包含更多数据。 -
请注意,虽然差异似乎微不足道,但
traceback.extract_stack()不包含对堆栈帧的引用这一事实非常重要。您对框架对象的每个引用都是内存泄漏(因为该框架引用的任何内容现在都不符合 gc 条件),因此在长时间运行的程序中这样做是一个很大的禁忌。 -
@roippi 不,不一定是内存泄漏。如果您不在局部变量中保留对框架对象的引用,那么您甚至没有引用循环。如果你确实有一个参考循环,你可以明确地打破它。即使您不理会引用循环,如果可以从该循环访问具有
__del__方法的任何内容并且您没有运行Python 3.4 或更高版本(请参阅PEP 442),这也只是内存泄漏.这些复杂的条件使得正确使用它棘手,但并非不可能,即使在一次运行数周的服务器中也是如此。 -
@delnan 我并不是在暗示 gc 无法检测到循环引用。我的意思是,如果您坚持那些框架对象引用(例如,顶级全局错误处理程序或其他东西),就会发生不好的事情。
-
@roippi 好吧,这只是一种可怕的说法,即“很多东西都可以从框架中获取”。这与任何其他参考文献没有根本不同。
标签: python inspect traceback sys