我试图创建一个用于记录的自定义属性(调用者的类名,模块名称等),并遇到一个奇怪的异常,告诉我在进程中创建的LogRecord实例没有必要的属性.经过一些测试,我最终得到了这个:
import logging
class MyLogger(logging.getLoggerClass()):
value = None
logging.setLoggerClass(MyLogger)
loggers = [
logging.getLogger(),
logging.getLogger(""),
logging.getLogger("Name")
]
for logger in loggers:
print(isinstance(logger, MyLogger), hasattr(logger, "value"))
Run Code Online (Sandbox Code Playgroud)
这段看似正确的代码产生:
False False
False False
True True
Run Code Online (Sandbox Code Playgroud)
错误或功能?
查看源代码,我们可以看到以下内容:
root = RootLogger(WARNING)
def getLogger(name=None):
if name:
return Logger.manager.getLogger(name)
else:
return root
Run Code Online (Sandbox Code Playgroud)
也就是说,导入模块时默认会创建根记录器.因此,每次查找根目录(传递假值,例如空字符串)时,logging.RootLogger无论是否有任何调用,您都将获得一个对象logging.setLoggerClass.
关于正在使用的记录器类,我们可以看到:
_loggerClass = None
def setLoggerClass(klass):
...
_loggerClass = klass
Run Code Online (Sandbox Code Playgroud)
这意味着全局变量保存将来使用的记录器类.
除此之外,看logging.Manager(使用者logging.getLogger),我们可以看到:
def getLogger(self, name):
...
rv = (self.loggerClass or _loggerClass)(name)
Run Code Online (Sandbox Code Playgroud)
也就是说,如果self.loggerClass未设置(除非您明确设置它,否则不会设置),使用全局变量中的类.
因此,这是一个功能.根记录器始终是一个logging.RootLogger对象,其他记录器对象是根据当时的配置创建的.
| 归档时间: |
|
| 查看次数: |
4276 次 |
| 最近记录: |