服务器故障中的

This question was migrated,因为可以在堆栈溢出中得到回答。
                            Migrated去年。
                        
                    
                
                            
                    
鉴于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,并且如果我们愿意的话,我们可以拍摄自己的祖父母,因此可以将根记录器的类型全部变形:

>>> root = logging.getLogger()
>>> root.__class__ = MyLogger
>>> root
<MyLogger root (WARNING)>


根记录器与其他记录器没有什么不同,除了它必须具有记录级别。如果您在实现MyLogger时遵守了Liskov substitution principle的规定,则此方法应该可以正常工作-到达根记录器的所有事件都将能够使用MyLogger的自定义项。

09-12 03:12