日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Python日志打印里logging.getLogger源碼分析詳解

瀏覽:13日期:2022-06-29 16:23:58
實踐環境

WIN 10

Python 3.6.5

函數說明

logging.getLogger(name=None)

getLogger函數位于logging/__init__.py腳本

源碼分析

_loggerClass = Logger# ...略 root = RootLogger(WARNING)Logger.root = rootLogger.manager = Manager(Logger.root) # ...略 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

結論:如函數注釋所述,如果調用getLogger時,如果沒有指定函數參數(即要獲取的日志打印器名稱)或者參數值不為真,則默認返回root打印器

Logger.manager.getLogger(self, name)源碼分析

該函數位于logging/__init__.py腳本

class Manager(object): ''' There is [under normal circumstances] just one Manager instance, which holds the hierarchy of loggers. ''' def __init__(self, rootnode): ''' Initialize the manager with the root node of the logger hierarchy. ''' self.root = rootnode self.disable = 0 self.emittedNoHandlerWarning = False self.loggerDict = {} self.loggerClass = None self.logRecordFactory = None 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 if not isinstance(name, str): raise TypeError(’A logger name must be a string’) _acquireLock() try: if name in self.loggerDict:rv = self.loggerDict[name]if isinstance(rv, PlaceHolder): ph = rv rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupChildren(ph, rv) self._fixupParents(rv) else:rv = (self.loggerClass or _loggerClass)(name) # _loggerClass = Loggerrv.manager = selfself.loggerDict[name] = rvself._fixupParents(rv) finally: _releaseLock() return rvLogger源碼分析

_nameToLevel = { ’CRITICAL’: CRITICAL, ’FATAL’: FATAL, ’ERROR’: ERROR, ’WARN’: WARNING, ’WARNING’: WARNING, ’INFO’: INFO, ’DEBUG’: DEBUG, ’NOTSET’: NOTSET,} # ...略 def _checkLevel(level): if isinstance(level, int): rv = level elif str(level) == level: if level not in _nameToLevel: raise ValueError('Unknown level: %r' % level) rv = _nameToLevel[level] else: raise TypeError('Level not an integer or a valid string: %r' % level) return rv # ...略class PlaceHolder(object): ''' PlaceHolder instances are used in the Manager logger hierarchy to take the place of nodes for which no loggers have been defined. This class is intended for internal use only and not as part of the public API. ''' def __init__(self, alogger): ''' Initialize with the specified logger being a child of this placeholder. ''' self.loggerMap = { alogger : None } def append(self, alogger): ''' Add the specified logger as a child of this placeholder. ''' if alogger not in self.loggerMap: self.loggerMap[alogger] = None class Logger(Filterer): ''' Instances of the Logger class represent a single logging channel. A 'logging channel' indicates an area of an application. Exactly how an 'area' is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of 'input processing' might include sub-areas 'read CSV files', 'read XLS files' and 'read Gnumeric files'). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be 'input' for the upper level, and 'input.csv', 'input.xls' and 'input.gnu' for the sub-levels. There is no arbitrary limit to the depth of nesting. ''' def __init__(self, name, level=NOTSET): ''' Initialize the logger with a name and an optional level. ''' Filterer.__init__(self) self.name = name self.level = _checkLevel(level) self.parent = None self.propagate = True self.handlers = [] self.disabled = False # ... 略

結論:如果調用logging.getLogger()時,有指定日志打印器名稱,且名稱為真(不為空字符串,0,False等False值),

1)如果名稱為不存在的日志打印器名稱,則,且參數值為真,但是即要獲取的日志打印器名稱)或者參數值不為真,則創建一個名為給定參數值的日志打印器,該日志打印器,默認級別默認為NOTSET,disable_existing_loggers配置為False,propagate配置為True。然后在日志打印器字典中記錄該名稱和日志打印器的映射關系,接著調用 _fixupParents(創建的日志打印器實例)類實例方法--為日志打印器設置上級日志打印器,最后返回該日志打印器。

2)如果名稱已存在日志打印器名稱,則獲取該日志打印器,然后判斷日志打印器是否為PlaceHolder類實例,如果是,則創建一個名為所給參數值的日志打印器,同第1)點,該日志打印器,默認級別默認為NOTSET,disable_existing_loggers配置為False,propagate配置為True。然后在日志打印器字典中記錄該名稱和日志打印器的映射關系,接著調用 _fixupParents(創建的打印器實例)類實例方法,_fixupChildren(PlaceHolder類實例--根據名稱獲取的日志打印器,新建的日志打印器實例)--為新建日志打印器設置上級日志打印器,為PlaceHolder類實例現有下級PlaceHolder日志打印器實例重新設置上級日志打印器,最后返回該日志打印器。

_fixupParents及_fixupChildren函數源碼分析

# _fixupParents # ...略class Manager(object): # ...略 def _fixupParents(self, alogger): ''' Ensure that there are either loggers or placeholders all the way from the specified logger to the root of the logger hierarchy. ''' name = alogger.name # 獲取日志打印器名稱 i = name.rfind('.') rv = None # 存放alogger日志打印器的上級日志打印器 while (i > 0) and not rv: # 如果名稱中存在英文的點,并且找到上級日志打印器 substr = name[:i] # 獲取名稱中位于最后一個英文的點的左側字符串(暫且稱至為 點分上級) if substr not in self.loggerDict: # 如果 點分上級 不存在日志打印器字典中self.loggerDict[substr] = PlaceHolder(alogger) # 創建PlaceHolder實例作為 點分上級 對應的日志打印器 # 繼續查找點分上級日志打印器 # 注意,這里的PlaceHolder僅是占位用,不是真的打印器,這里為了方便描述,暫且稱之為PlaceHolder日志打印器 else: # 否則obj = self.loggerDict[substr] # 獲取 點分上級 對應的日志打印器if isinstance(obj, Logger): # 如果為Logger實例,如果是,則跳出循環,執行 # 為日志打印器設置上級 rv = objelse: # 否則 assert isinstance(obj, PlaceHolder) # 斷言它為PlaceHolder的實例 obj.append(alogger) # 把日志打印器添加為點分上級對應的PlaceHolder日志打印器實例的下級日志打印器 執行 # 繼續查找點分上級日志打印器 i = name.rfind('.', 0, i - 1) # 繼續查找點分上級日志打印器 if not rv: # 找不到點分上級、或者遍歷完所有點分上級,都沒找到上級日志打印器 rv = self.root # 則 把root日志打印器設置為alogger日志打印器的上級日志打印器 alogger.parent = rv # 為日志打印器設置上級 def _fixupChildren(self, ph, alogger): ''' Ensure that children of the placeholder ph are connected to the specified logger. ''' name = alogger.name # 獲取日志打印器名稱 namelen = len(name) # 獲取日志打印器名稱長度 for c in ph.loggerMap.keys(): # 遍歷獲取的PlaceHolder日志打印器實例的子級日志打印器 #The if means ... if not c.parent.name.startswith(nm) if c.parent.name[:namelen] != name: # 如果PlaceHolder日志打印器實例名稱不以alogger日志打印器名稱為前綴,alogger.parent = c.parent # 那么,設置alogger日志打印器的上級日志打印器為PlaceHolder日志打印器c.parent = alogger # 設置alogger日志打印器為PlaceHolder日志打印器原有下級PlaceHolder日志打印器的上級

結論:日志打印器都是分父子級的,這個父子層級是怎么形成的,參見上述函數代碼注解

到此這篇關于Python日志打印里logging.getLogger源碼分析詳解的文章就介紹到這了,更多相關Python logging.getLogger源碼分析內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Python 編程
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
69堂精品视频在线播放| 999久久久国产精品| 免费在线观看一区二区三区| 亚洲香蕉网站| 欧美性感美女一区二区| 在线观看精品| 99精品视频在线| 亚洲韩日在线| 欧美日韩视频| 午夜亚洲一区| 亚洲毛片一区| 欧美日韩一区二区国产| 国产精品中文字幕亚洲欧美| 麻豆久久一区二区| 国产精品13p| 久久精品123| 色婷婷久久久| 黄页网站一区| 亚洲a成人v| 国产精品久久久久久久久免费高清| 国产精品美女午夜爽爽| 精品少妇av| 亚洲91视频| 免费日韩av片| 日韩精品久久久久久| 国产精品大片| 欧美日韩视频免费观看| 国产日韩综合| 日韩激情中文字幕| 国产精品18| 久久久久99| 影院欧美亚洲| 日韩黄色av| 国产一区一一区高清不卡| 成人自拍av| 一区二区精品| 精品视频在线观看网站| 欧美日一区二区| 视频一区中文字幕国产| 91av一区| 日韩伦理在线一区| 性色一区二区| 欧美国产另类| 九九综合九九| 国产精品一区二区精品视频观看 | 国产精品videossex| av免费不卡国产观看| 欧美日韩国产一区精品一区| 日韩国产一二三区| 日本韩国欧美超级黄在线观看| 亚洲欧美日韩国产一区二区| 美腿丝袜亚洲三区| 一区在线免费观看| 久久丁香四色| 不卡一区2区| 日本va欧美va欧美va精品| 日本久久黄色| 蜜桃av一区二区| 成人在线视频区| 免费不卡在线视频| 国产精品xx| 视频精品一区| 久久久久网站| 国产日本亚洲| 亚洲精品2区| 欧美a级一区二区| 美女尤物久久精品| 亚洲深夜视频| 97久久超碰| 亚洲激情欧美| 国产自产自拍视频在线观看| 亚洲精品乱码| 中文另类视频| 国产精品三p一区二区| 伊人影院久久| 都市激情国产精品| 日本成人在线视频网站| 国产综合婷婷| 国产91在线播放精品| 日韩福利在线观看| 日韩午夜黄色| 国产超碰精品| 欧美极品中文字幕| 日韩影片在线观看| 亚洲精品2区| 日韩成人免费| 日韩欧美三区| 狠狠色综合网| 亚洲成人va| 久久亚洲人体| 青草av.久久免费一区| 亚洲综合丁香| 九一国产精品| 亚洲不卡系列| 黄色aa久久| 国产精品啊啊啊| 日韩欧美精品一区二区综合视频| 美女网站一区| 91精品一区国产高清在线gif| 九九久久国产| 国产激情久久| 久久国产欧美日韩精品| 免费不卡在线观看| 夜夜嗨一区二区| 一区二区三区视频免费观看| 97se综合| 日韩黄色大片| www.com.cn成人| av资源亚洲| av中文资源在线资源免费观看| 国产精品毛片久久久| 国产丝袜一区| 国产免费av一区二区三区| 日韩不卡在线观看日韩不卡视频 | 久久wwww| 国产精品流白浆在线观看| 欧美一级一区| 日本高清久久| 久久国产欧美日韩精品| 欧美精品国产| 国产美女亚洲精品7777| 国产亚洲欧美日韩精品一区二区三区| 日本亚洲不卡| 日韩精品免费视频一区二区三区| 亚洲午夜国产成人| 中文字幕日韩亚洲| 亚洲区第一页| 日韩激情一区二区| 日本一区二区三区中文字幕| 亚洲人成高清| 日本欧美久久久久免费播放网| 日韩精品一区二区三区中文在线| 色综合视频一区二区三区日韩 | 国产精品久久久久av蜜臀| 国产精品一区高清| 麻豆精品在线播放| 精品美女在线视频| 中文字幕人成乱码在线观看| 九色porny丨国产首页在线| 亚洲福利精品| 国产精品美女久久久浪潮软件| 妖精视频成人观看www| 在线精品一区二区| 日韩av网站免费在线| 久久伊人久久| 麻豆精品蜜桃| 亚洲免费黄色| 天堂va在线高清一区| 国产精品三级| 91日韩免费| 日韩亚洲在线| 日本va欧美va欧美va精品| 久久99精品久久久久久园产越南 | 国产精品成人一区二区网站软件| 久久精品国产网站| 日韩精品首页| 久久亚洲欧洲| 国产精品手机在线播放| 成人国产精品| 五月天久久网站| 亚洲精品字幕| 老牛国内精品亚洲成av人片| 久久蜜桃精品| 亚洲精品观看| 丰满少妇一区| 欧美日韩国产亚洲一区| 欧美午夜三级| 国产中文欧美日韩在线 | 国产日本精品| 成人片免费看| 三级亚洲高清视频| 国产精品对白久久久久粗| 高清av不卡| 亚洲精品少妇| 欧美亚洲日本精品| 中文不卡在线| 国产成人精品一区二区三区免费 | 亚洲综合福利| 精品国产黄a∨片高清在线| 欧美日韩一二三四| 欧美日韩视频免费看| 国产在线观看www| 在线看片日韩| 欧美好骚综合网| 亚洲精品日本| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 羞羞答答国产精品www一本 | 亚洲网址在线观看| 97精品一区二区| 亚洲欧美在线专区| 日韩深夜视频| 亚洲欧洲美洲国产香蕉| 国产h片在线观看| 日韩一区二区三区免费视频| 亚洲性色av| 日韩免费精品| 亚洲一级影院| 久久免费视频66| 亚洲精品日韩久久| 亚洲高清毛片|