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

In the file where I define a mixin class, how do I use the logger from the file where the mixin is used?

我正在抽象出一大块重复的代码,我在其中设置了许多 classes 的记录器。

我想要一个 class,其中混合允许我使用记录器对象实例化 class,或者使用该 class 模块中的默认模块.

我会这样使用它:

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 中获取该记录器,并因此将其完全抽象化(如果是,如何?)或者我是否必须为每个 class 覆盖 logger 属性 ?

与其在模块中实例化一个全局变量然后尝试访问它,不如直接使用 getLogger 根据模块名称获取记录器。此外,我只在 __init__ 中执行一次默认设置,而不是在 属性:

中的每次查找
self._logger = logger or logging.getLogger(self.__class__.__module__)

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

完整的 mixin 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