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

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

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

瀏覽:15日期:2022-06-29 16:23:58
實踐環(huán)境

WIN 10

Python 3.6.5

函數(shù)說明

logging.getLogger(name=None)

getLogger函數(shù)位于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

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

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

該函數(shù)位于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,F(xiàn)alse等False值),

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

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

_fixupParents及_fixupChildren函數(shù)源碼分析

# _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) # 創(chuàng)建PlaceHolder實例作為 點分上級 對應的日志打印器 # 繼續(xù)查找點分上級日志打印器 # 注意,這里的PlaceHolder僅是占位用,不是真的打印器,這里為了方便描述,暫且稱之為PlaceHolder日志打印器 else: # 否則obj = self.loggerDict[substr] # 獲取 點分上級 對應的日志打印器if isinstance(obj, Logger): # 如果為Logger實例,如果是,則跳出循環(huán),執(zhí)行 # 為日志打印器設置上級 rv = objelse: # 否則 assert isinstance(obj, PlaceHolder) # 斷言它為PlaceHolder的實例 obj.append(alogger) # 把日志打印器添加為點分上級對應的PlaceHolder日志打印器實例的下級日志打印器 執(zhí)行 # 繼續(xù)查找點分上級日志打印器 i = name.rfind('.', 0, i - 1) # 繼續(xù)查找點分上級日志打印器 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日志打印器的上級

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

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

標簽: Python 編程
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
高潮一区二区| 福利视频一区| 国产精品一区二区99| 中文不卡在线| 99热精品在线| 在线观看亚洲精品福利片| 伊人久久亚洲| 日本久久一区| 国产精品亚洲产品| 欧美日韩亚洲一区在线观看| 国产丝袜一区| 国产精东传媒成人av电影| 日本久久二区| 国产精品主播在线观看| 国产黄色精品| 福利视频一区| 欧美日韩国产一区精品一区| 久久精品国产68国产精品亚洲| 国产成人久久精品麻豆二区 | 视频一区中文字幕精品| 日本一不卡视频| 嫩草伊人久久精品少妇av杨幂| 美女毛片一区二区三区四区最新中文字幕亚洲| 久久久国产精品网站| 99久久婷婷| 日韩福利视频一区| 国产乱码午夜在线视频| 亚洲综合不卡| 精品国产网站| 99精品视频精品精品视频| 日韩精品网站| 日本中文字幕视频一区| 激情综合婷婷| 久久国产精品久久久久久电车| 欧美日韩中文| 五月婷婷亚洲| 国产精品成人自拍| 国产亚洲网站| 高清精品久久| 69堂免费精品视频在线播放| 国产99在线| 久久精品99国产国产精| 亚洲国产一区二区三区在线播放| 国产亚洲高清一区| 另类av一区二区| 国产精品sm| 亚洲精品综合| 91成人精品视频| 老鸭窝一区二区久久精品| 丝袜美腿亚洲一区| 色偷偷偷在线视频播放| 国产三级一区| 亚洲欧美久久精品| 欧美精品自拍| 欧美日韩国产免费观看视频| 成人在线视频免费| 久久av国产紧身裤| 欧美日韩1区| 日韩高清在线观看一区二区| 老司机精品久久| 九色porny丨国产首页在线| 日韩av中文字幕一区二区| 亚洲天堂av资源在线观看| 一区在线免费| 午夜一区在线| 欧美专区一区二区三区| 水蜜桃久久夜色精品一区的特点| 亚洲激情久久| 香蕉久久久久久久av网站| 五月婷婷亚洲| 视频一区视频二区中文字幕| 午夜久久久久| 中文字幕日韩亚洲| 日韩精彩视频在线观看| 欧美日韩视频免费看| 亚洲精品裸体| 欧美亚洲国产日韩| 国产精品伦一区二区| 国产精品亚洲人成在99www| 国产欧美亚洲一区| 精品国产成人| 91精品在线观看国产| 国产aⅴ精品一区二区四区| 国产一区不卡| 精品免费av| 色偷偷色偷偷色偷偷在线视频| 欧美另类中文字幕| 欧美激情 亚洲a∨综合| 蜜桃精品在线| 亚洲另类av| 国产精品嫩模av在线| 日韩中文视频| 国产亚洲精品美女久久久久久久久久| 精品国产一区二| 国产精品老牛| 国产成人a视频高清在线观看| 鲁大师影院一区二区三区| 亚洲精品影视| 欧美二区视频| 91亚洲人成网污www| 国产欧美日韩影院| 一区二区国产在线| 久久久成人网| 国产一区二区三区不卡av | 国产精品igao视频网网址不卡日韩| 99精品在线观看| 青青草精品视频| 久久精品国产一区二区| 欧美日韩一区二区三区不卡视频 | 国产精品社区| 麻豆精品久久久| 奇米狠狠一区二区三区| 噜噜噜躁狠狠躁狠狠精品视频 | 亚洲视频电影在线| 福利一区二区免费视频 | 香蕉成人av| 在线日韩成人| 一区在线观看| 一区在线免费| 国产免费成人| 蜜桃久久久久久| 蜜臀av亚洲一区中文字幕| 久久亚洲影院| 欧美成a人片免费观看久久五月天| 国产麻豆精品| 国产免费成人| 女同性一区二区三区人了人一| 成人午夜在线| 国产成人免费视频网站视频社区| 国产欧美在线| 国产精品成人**免费视频| 樱桃成人精品视频在线播放| 国产一区二区三区四区大秀| 亚洲1区在线观看| 噜噜噜久久亚洲精品国产品小说| 亚洲黄色影院| 日本欧洲一区二区| 日韩高清电影免费| 国产精品调教| 国产成人精品一区二区免费看京 | 久久只有精品| 老色鬼精品视频在线观看播放| 国产精品自拍区| 日本视频中文字幕一区二区三区| 日韩中文av| 欧美片第1页综合| 欧美一区91| 久久97视频| 亚洲福利专区| 伊人久久一区| 国产精品传媒麻豆hd| 日韩高清欧美| 夜夜嗨一区二区三区| 亚洲精品无播放器在线播放| 日韩高清二区| 日韩久久电影| 午夜久久影院| 国产精品亚洲产品| 天堂√中文最新版在线| 在线视频观看日韩| 色狠狠一区二区三区| 欧美国产专区| 蜜臀久久精品| 中文字幕成人| 国产在线不卡一区二区三区| 国产精选在线| 99香蕉国产精品偷在线观看| 欧美中文高清| 亚洲午夜视频| 国产精品亲子伦av一区二区三区| 日韩一区二区三区免费| 在线观看一区| 日韩欧美精品| 日韩午夜黄色| 国产精品久久久久av蜜臀| 蜜桃成人av| 国产一区二区亚洲| 亚洲久久视频| 亚洲高清激情| 成人羞羞在线观看网站| 日本免费新一区视频| 欧美精品一区二区三区精品| 免费看久久久| 亚洲精品在线国产| 999久久久亚洲| 免费日韩一区二区三区| 伊人久久大香伊蕉在人线观看热v| 麻豆国产精品| 免费高清在线一区| 欧美黄色网页| 中文字幕av一区二区三区人 | 一区二区国产精品| 秋霞影视一区二区三区| 国产乱码精品一区二区三区四区| 亚洲男人在线| 五月国产精品| 日本a级不卡| 国产日韩视频在线| 日本午夜精品视频在线观看| 欧美日韩视频一区二区三区|