在定义mixin类的文件中,如何使用使用mixin的文件中的记录器?

问题描述

我正在提取重复的代码块,在许多类中都设置了记录器。

我想创建一个类,其中的mixin允许我使用logger对象实例化该类,或使用该类的模块中的认模块。

我会这样使用它:

import logging
from .mixin import LoggerMixin


resource_module_logger = logging.getLogger(__name__)


class MyResource(LoggerMixin):
    """ Instantiate this class to do something.

    If instantiated with a custom logger,then all log outputs will go to that. Otherwise,they'll go to resource_module_logger

    ```
    MyResource().do_something()  # Does something while logging to resource module logger.
    MyResource(logger=logging.getLogger("specific"))  # does something while logging to a specific logger.
    ```
    """

    def do_something(self):
        self.logger.info("This message will go to the default module level logger,unless a custom logger was specified at instantiation")

到目前为止,我的mixin是:

import logging


this_is_not_the_logger_im_looking_for = logging.getLogger(__name__)


class LoggerMixin:

    def __init__(self,*args,logger=None,**kwargs):

        self._logger = logger
        super().__init__(*args,**kwargs)

    @property
    def logger(self):
        # How do I get the resource module logger for the MyResource class which this is mixed into???
        resource_module_logger = ?????????????
        return self._logger or resource_module_logger

问题 是否可以从mixin中获取该记录器,从而完全抽象化该记录器(如果是,则如何?),还是我必须为每个类重写logger属性

解决方法

您可以直接使用getLogger来根据模块名称获取记录器,而不必在模块中实例化全局变量然后尝试访问它。另外,我只会在__init__中进行一次默认设置,而不是对属性中的每次查找进行设置:

self._logger = logger or logging.getLogger(self.__class__.__module__)

编辑-包括完整的解决方案

完整的混合loggable.py将是:

import logging


class Loggable:
    """ Mixin to allow instantiation of a class with a logger,or by default use the module logger from that class

    ```
    class MyResource(Logged):
        def do_something(self):
            self.logger.info('write to a logger')

    MyResource().do_something()  # Log statements go to the default logger for the module in which MyResource is a member
    MyResource(logger=logging.getLogger("specific"))  # Log statements go to the specific logger.
    ```
    """

    def __init__(self,*args,logger=None,**kwargs):
        super().__init__(*args,**kwargs)
        self._logger = logger or logging.getLogger(self.__class__.__module__)

    @property
    def logger(self):
        return self._logger