Python 在日志模块的上下文中,窃取的含义是什么
查看Python 在日志模块的上下文中,窃取的含义是什么,python,python-2.7,logging,Python,Python 2.7,Logging,查看日志记录模块并看到以下内容: # next bit filched from 1.5.2's inspect.py def currentframe(): """Return the frame object for the caller's stack frame.""" try: raise Exception except: return sys.exc_info()[2].tb_frame.f_back if hasattr(
日志记录
模块并看到以下内容:
# next bit filched from 1.5.2's inspect.py
def currentframe():
"""Return the frame object for the caller's stack frame."""
try:
raise Exception
except:
return sys.exc_info()[2].tb_frame.f_back
if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
# done filching
“窃取”一词在本文中的含义是什么?这是您不想作为一个好例子的代码!首先,它是特定于CPython实现的,因此在PyPy、Jython、ironpython等环境下无法工作 我假定作者引发异常是为了访问调用例程的堆栈帧,或者可能是调用方的调用方 “窃取”是未经许可的行为,因此这只是一种充满内疚的说法,“我从开源库复制并粘贴了。”
# next bit filched from 1.5.2's inspect.py
这个词的意思是“抄袭自”。也就是说,自Python版本1.5.2以来,这个特定的代码序列已经存在了很长时间
这里发生了什么(编辑:问题的这一部分被编辑掉了!)很简单但很微妙。任何异常都会导致Python系统找到最里面的、当前处于活动状态的处理程序,但
处理程序除外。在本例中,这是下一行,因此:
try:
raise Exception
except:
...
直接进入…
行。然而,raise
有一个副作用,这是整个过程的关键。副作用是,raise
使回溯堆栈包含指向raise
行本身的执行状态,作为最近的条目
sys.exc_info()
函数返回一个包含三个元素的元组:异常的类型、异常的值此处未传递任何值,因为处理程序不需要一个元素和(整个)回溯堆栈。[2]
从元组中提取此回溯堆栈,丢弃异常类型和值
回溯堆栈的结构有些复杂,但在每个回溯堆栈实例中都有一个.tb\u frame
属性。这包含有关发生异常时处于活动状态的堆栈帧的信息。由于这是一个函数激活堆栈,它的前身是调用currentframe
时处于活动状态的状态,因此这是调用方的帧
这种定位调用者帧的方法不是很有效(而且,对于CPython解释器来说,也是特定的),因此如果sys
具有\u getframe
函数,文件将重新绑定currentframe
以调用sys.\u getframe(3)
。(我不确定常量3在这里做什么,因为另一个版本有效地返回了sys.\u getframe(0)
将返回。编辑2:在进一步检查时,神奇常量3负责调用\u log
的日志处理程序,该处理程序调用findCaller
,该处理程序调用currentframe
。这是另一个效率黑客攻击,因为findCaller
会爬升到每个堆栈帧中,查找某个文件中出现的堆栈帧r比日志记录模块代码本身要好。这将从一个更好的点开始。)
1请记住,堆栈是以后进先出(LIFO)方式运行的任何数据结构。Python解释器管理一系列不同但或多或少是同时发生的堆栈,包括异常处理程序和正常的函数调用机制。“被盗的”“拿走的”-在本文中:“复制的”我猜是异常是专门抛出的,以便返回回溯帧