歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Python標准庫logging模塊代碼分析

問題1:如何獲取caller的(文件名,行號,函數名)?

當新增一條log記錄時,最終將調用Logger類的_log方法,這個方法首先會創建一個LogRecord對象。LogRecord對象需要(filename, lineno, funcname)參數信息。這是通過如下語句得到的:

fn, lno, func = self.findCaller()

findCaller內容如下:

        f = currentframe()  #f是frame對象,每個方法調用生成一個frame對象,放在程序堆棧中。
        if f is not None:
            f = f.f_back
        rv = "(unknown file)", 0, "(unknown function)"
        while hasattr(f, "f_code"):
            co = f.f_code  #獲取code對象,它包含filename屬性,funcname屬性
            filename = os.path.normcase(co.co_filename)
            if filename == _srcfile:  #_srcfile是這個模塊文件自己的文件名,當文件名不再相同時
                f = f.f_back          # 得到外部調用者的frame,這就是需要的。
                continue
            rv = (filename, f.f_lineno, co.co_name)
            break
        return rv

currentframe函數的定義:

def currentframe():
    """Return the frame object for the caller's stack frame."""
    try:
        raise Exception    #拋出異常,將生成traceback對象,其中包含frame對象。
    except:
        #sys.exc_traceback.tb_frame當前的frame, f_back調用著的frame
        return sys.exc_traceback.tb_frame.f_back
#sys._getframe(3)返回的並不是當前的frame,3應該是計算好了的,減少循環的次數,返回的是logger.error()的frame
if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)

Copyright © Linux教程網 All Rights Reserved