鉴于这段 Python:
logging.setLoggerClass(MyLogger)
logger = logging.getLogger()
print(type(logger))
...我认为是正确实现的 MyLogger 类:
class MyLogger(logging.getLoggerClass()):
def __init__(self, name: str=os.path.basename(__file__)) -> None:
logging.Logger.__init__(self, name=name)
我希望 GetLogger 返回 MyLogger 的一个实例,但它没有:
<class 'logging.RootLogger'>
没有错误或警告。当我调用 logging.getLogger() 时,似乎永远不会调用 MyLogger 构造函数
我做错了什么?
最佳答案
当您调用 setLoggerClass(...)
时影响根记录器的创建已经太晚了。根记录器已经实例化,它是在执行 import logging
时创建的,并且作为 RootLogger
实例存在于日志模块的命名空间中。 getLogger()
调用只是返回现有实例。
但是,您随后创建的任何其他记录器,例如logging.getLogger('mylogger')
,将是您的子类的一个实例。通常你会在你的模块的顶部有这个:
log = logging.getLogger(__name__)
这个日志将由一个 MyLogger
实例。
现在,您真的不应该关心根记录器是什么类,因为无论如何您都不希望它处理事件。然而,由于这是 Python,如果我们真的愿意,我们可以射杀我们自己的祖 parent ,所以可以完全相同地改变根记录器的类型:
>>> root = logging.getLogger()
>>> root.__class__ = MyLogger
>>> root
<MyLogger root (WARNING)>
根记录器与任何其他记录器没有什么不同,只是它必须具有日志记录级别。只要你遵守Liskov substitution principle在实现 MyLogger
时,这应该可以正常工作 - 任何到达根记录器的事件都将能够使用 MyLogger
的自定义。
关于logging - Python 3.7 logging.setLoggerClass() 不是,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51938027/