在日志记录模块的上下文中缓存是什么意思

时间:2018-12-23 09:48:49

标签: python python-2.7 logging

浏览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(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
# done filching

在这种情况下,“过滤”一词是什么意思?

2 个答案:

答案 0 :(得分:3)

这是您不希望作为示例的代码!首先,它特定于CPython实现,因此无法在PyPy,Jython,Iron Python等环境下使用。

我认为作者提出了异常,以便访问调用例程的堆栈框架,或者可能是调用者的调用者。

“ Filching”未经许可即被盗用,因此这只是一种内的表达方式:“我是从开源库复制并粘贴的。”

答案 1 :(得分:2)

作为barny commented注释内容为:

# next bit filched from 1.5.2's inspect.py

使用该词来表示“复制自”。也就是说,从Python版本1.5.2开始,这种特殊的代码序列已经存在了很长时间。

这里的正在进行是什么(编辑:问题的这一部分已被删除!)很简单但很微妙。任何异常都会导致Python系统找到最内部的当前活动except处理程序。在这种情况下,这是下一行—

try:
    raise Exception
except:
    ...

直接进入...行。但是,raise具有副作用,这是整件事的关键。副作用是raise使 traceback堆栈包含指向最近的{sup> 1 指向raise行的执行状态本身。

sys.exc_info()函数返回一个包含三个元素的元组:异常的类型,异常的值(此处未传递值,因为处理程序不需要一个值)和(整个)回溯堆栈。 [2]从元组中提取此追溯堆栈,并丢弃异常类型和值。

回溯栈的结构有些复杂,但是每个回溯栈实例中都有一个.tb_frame属性。它包含有关发生异常时处于活动状态的堆栈帧的信息。由于这是函数激活的堆栈,因此它的前身是在调用currentframe时处于活动状态,因此这是调用者的框架。

这种定位调用方框架的方法不是很有效(并且,holdenweb points out特定于CPython解释器),因此,如果sys具有_getframe函数,则文件-绑定currentframe以调用sys._getframe(3)。 (我不确定常数3在这里做什么,因为另一个版本有效地返回了sys._getframe(0)将返回的内容。编辑2:在进一步检查时,魔术常数3负责调用{{1}的日志处理程序。 }会调用_log,这又会调用findCaller。这是另一种效率攻击,因为currentframe会在每个堆栈帧中向上爬,以查找在文件而非中出现的一个日志模块的代码本身。这样会更好。)


1 请记住,堆栈是任何以后进先出(LIFO)方式运行的数据结构。 Python解释器管理一堆不同的(或多或少)同时的堆栈,包括异常处理程序和常规的函数调用机制。