问题2: Logger对象的层级,父子关系如何实现的?
首先,logging模块中logger层级关系是一个树形关系的结构,这个关系的树根是'root'。
root = RootLogger(WARNING) #RootLogger类是Logger的子类,无特殊功能,只是定义名字为‘root’。
Logger.root = root
Logger.manager = Manager(Logger.root)
当调用logging.getLogger(),用以获取某个Logger时,如果参数为空,则返回‘root’。否则,调用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