最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

代碼解析python標(biāo)準(zhǔn)庫logging模塊

 更新時(shí)間:2022年05月20日 11:34:42   作者:wangst4321  
這篇文章主要為大家介紹了代碼解析python標(biāo)準(zhǔn)庫logging模塊,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

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

當(dāng)新增一條log記錄時(shí),最終將調(diào)用Logger類的_log方法,這個(gè)方法首先會(huì)創(chuàng)建一個(gè)LogRecord對象。LogRecord對象需要(filename, lineno, funcname)參數(shù)信息。這是通過如下語句得到的:

fn, lno, func = self.findCaller()  

findCaller內(nèi)容如下:

        f = currentframe()  #f是frame對象,每個(gè)方法調(diào)用生成一個(gè)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是這個(gè)模塊文件自己的文件名,當(dāng)文件名不再相同時(shí)
                f = f.f_back          # 得到外部調(diào)用者的frame,這就是需要的。
                continue
            rv = (filename, f.f_lineno, co.co_name)
            break
        return rv

currentframe函數(shù)的定義:

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

問題2: Logger對象的層級(jí),父子關(guān)系如何實(shí)現(xiàn)的?

首先,logging模塊中l(wèi)ogger層級(jí)關(guān)系是一個(gè)樹形關(guān)系的結(jié)構(gòu),這個(gè)關(guān)系的樹根是'root'。

root = RootLogger(WARNING)     #RootLogger類是Logger的子類,無特殊功能,只是定義名字為‘root'。
Logger.root = root
Logger.manager = Manager(Logger.root)

當(dāng)調(diào)用logging.getLogger(),用以獲取某個(gè)Logger時(shí),如果參數(shù)為空,則返回‘root’。否則,調(diào)用Manager的getLogger()方法獲取Logger。

def getLogger(name=None):
    """
    Return a logger with the specified name, creating it if necessary.
    If no name is specified, return the root logger.
    """
    if name:
        return Logger.manager.getLogger(name)
    else:
        return root

Manager的getLogger()定義如下:

    def getLogger(self, name):
        """
        Get a logger with the specified name (channel name), creating it
        if it doesn't yet exist. This name is a dot-separated hierarchical
        name, such as "a", "a.b", "a.b.c" or similar.
        If a PlaceHolder existed for the specified name [i.e. the logger
        didn't exist but a child of it did], replace it with the created
        logger and fix up the parent/child references which pointed to the
        placeholder to now point to the logger.
        """
        rv = None
        _acquireLock()
        try:
            if name in self.loggerDict:
                rv = self.loggerDict[name]
                if isinstance(rv, PlaceHolder):
                    ph = rv
                    rv = _loggerClass(name)
                    rv.manager = self
                    self.loggerDict[name] = rv
                    self._fixupChildren(ph, rv)
                    self._fixupParents(rv)
            else:
                rv = _loggerClass(name)
                rv.manager = self
                self.loggerDict[name] = rv
                self._fixupParents(rv)
        finally:
            _releaseLock()
        return rv

Manager對象中的loggerDict字典,存放logger名字和logger對象的映射關(guān)系。PlaceHolder類,是一個(gè)容器。

例如,名字為'sell'的PlaceHolder對象,首先還不存在'sell'的logger,然后,所以以'sell‘開頭的logger在這個(gè)對象內(nèi)都存在一個(gè)引用,如'sell.food','sell.cloth.china'等已有的logger對象。 當(dāng)調(diào)用getLogger()獲取一個(gè)未存在的logger時(shí),如名字為'level1.level2', 首先創(chuàng)建一個(gè)名字為'level1.level2'的logger對象,并存于loggerDict中。然后,調(diào)用_fixupParents()。

_fixupParents()的作用:

在這個(gè)名字的層級(jí)鏈上,找到第一個(gè)logger對象,將其作為父親,并返回。鏈上不是logger對象的名字,創(chuàng)建一個(gè)PlaceHolder對象(如果未創(chuàng)建),將自己加入其中。

例如,新增‘level1.level2.level3’的logger,調(diào)用_fixupParents將創(chuàng)建一個(gè)名字為'level1.level2‘的PlaceHolder對象,創(chuàng)建一個(gè)名字為’level1‘的PlaceHolder對象,并將’level1.level2.level3‘這個(gè)logger分別加入以上兩個(gè)PlaceHolder對象容器內(nèi),將它的父親設(shè)定為’root‘。

總之,_fixupParents是使logger對象指向真正的父親節(jié)點(diǎn)(logger對象),并將logger自己加入到所有上層的PlaceHolder對象容器內(nèi)。

如果獲取一個(gè)名字已存在于loggerDict中,并且這個(gè)名字對應(yīng)的是一個(gè)先前創(chuàng)建的PlaceHolder對象。首先,創(chuàng)建一個(gè)對應(yīng)名字的logger對象。然后,調(diào)用_fixupChild(),修正這個(gè)PlaceHolder對象所包含的下游logger對象的父親。最后,調(diào)用_fixupParent(),作用與上一步相同。

父子層級(jí)關(guān)系,主要作用是,當(dāng)logger對象的propagate屬性值1(默認(rèn)值)時(shí),每條logRecord記錄都會(huì)傳給父logger處理。這樣可以只需要定義好‘root’根logger對象,其他的logger定義個(gè)名字,根據(jù)模塊名,類名等,然后綁定一個(gè)NullHandler。最后,所有的logRecord將交給’root‘統(tǒng)一處理處理。這是多模塊產(chǎn)生統(tǒng)一格式log的方式。

以上就是代碼解析python標(biāo)準(zhǔn)庫logging模塊的詳細(xì)內(nèi)容,更多關(guān)于python標(biāo)準(zhǔn)庫logging模塊的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python實(shí)現(xiàn)mysql數(shù)據(jù)庫更新表數(shù)據(jù)接口的功能

    Python實(shí)現(xiàn)mysql數(shù)據(jù)庫更新表數(shù)據(jù)接口的功能

    這篇文章主要給大家介紹了關(guān)于Python如何實(shí)現(xiàn)mysql數(shù)據(jù)庫更新表數(shù)據(jù)接口功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • Python實(shí)現(xiàn)將內(nèi)容寫入文件的五種方法總結(jié)

    Python實(shí)現(xiàn)將內(nèi)容寫入文件的五種方法總結(jié)

    本篇帶你詳細(xì)看一下python將內(nèi)容寫入文件的方法以及細(xì)節(jié),主要包括write()方法、writelines()?方法、print()?函數(shù)、使用?csv?模塊、使用?json?模塊,需要的可以參考一下
    2023-04-04
  • 舉例講解Python常用模塊

    舉例講解Python常用模塊

    今天小編就為大家分享一篇關(guān)于舉例講解Python常用模塊,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 詳解Python中靜態(tài)類型語言的寫法

    詳解Python中靜態(tài)類型語言的寫法

    眾所周知,python是一種動(dòng)態(tài)類型語言,但是,從v3.6版本開始,開始支持靜態(tài)類型的寫法,下面小編就來和大家聊聊Python中靜態(tài)類型語言的具體寫法吧
    2023-07-07
  • Python進(jìn)階之路模塊、包和異常處理詳解

    Python進(jìn)階之路模塊、包和異常處理詳解

    這篇文章主要介紹了Python進(jìn)階之路模塊、包和異常處理的相關(guān)資料,文中通過實(shí)例演示,展示了如何構(gòu)建模塊化的應(yīng)用并遵循最佳實(shí)踐,需要的朋友可以參考下
    2024-12-12
  • Python常用隨機(jī)數(shù)與隨機(jī)字符串方法實(shí)例

    Python常用隨機(jī)數(shù)與隨機(jī)字符串方法實(shí)例

    這篇文章主要介紹了Python常用隨機(jī)數(shù)與隨機(jī)字符串方法實(shí)例,本文講解了隨機(jī)整數(shù)、隨機(jī)選取0到100間的偶數(shù)、隨機(jī)浮點(diǎn)數(shù)、隨機(jī)字符串等常用隨機(jī)方法,需要的朋友可以參考下
    2015-04-04
  • pyqt5 從本地選擇圖片 并顯示在label上的實(shí)例

    pyqt5 從本地選擇圖片 并顯示在label上的實(shí)例

    今天小編就為大家分享一篇pyqt5 從本地選擇圖片 并顯示在label上的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-06-06
  • Python PyQt5實(shí)戰(zhàn)項(xiàng)目之文件拷貝器的具體實(shí)現(xiàn)詳解

    Python PyQt5實(shí)戰(zhàn)項(xiàng)目之文件拷貝器的具體實(shí)現(xiàn)詳解

    PyQt5以一套Python模塊的形式來實(shí)現(xiàn)功能。它包含了超過620個(gè)類,600個(gè)方法和函數(shù)。本篇文章手把手帶你用PyQt5實(shí)現(xiàn)一個(gè)簡單的文件拷貝器,大家可以在過程中查缺補(bǔ)漏,提升水平
    2021-11-11
  • 詳解Python 4.0 預(yù)計(jì)推出的新功能

    詳解Python 4.0 預(yù)計(jì)推出的新功能

    這篇文章主要介紹了詳解Python 4.0 預(yù)計(jì)推出的新功能,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-07-07
  • Python算法繪制特洛伊小行星群實(shí)現(xiàn)示例

    Python算法繪制特洛伊小行星群實(shí)現(xiàn)示例

    這篇文章主要介紹了Python算法繪制特洛伊小行星群實(shí)現(xiàn)示例,這個(gè)小示例完成后非常的有意思也會(huì)使你在Python學(xué)習(xí)的道路上感到一絲絲小成就
    2021-10-10

最新評論

铁力市| 富源县| 南康市| 肇东市| 长丰县| 洛宁县| 樟树市| 襄垣县| 锦屏县| 陇川县| 苍梧县| 天镇县| 鄯善县| 绍兴县| 犍为县| 阳山县| 额尔古纳市| 潼南县| 漾濞| 奎屯市| 龙南县| 达拉特旗| 枞阳县| 亚东县| 壤塘县| 桐庐县| 广饶县| 通山县| 鸡西市| 五华县| 剑河县| 托克逊县| 洛隆县| 来凤县| 洪洞县| 安岳县| 黄浦区| 大渡口区| 大姚县| 德阳市| 西吉县|