#python #class #logging #mixins #superclass
#python #класс #ведение журнала #mixins #суперкласс
Вопрос:
Я абстрагируюсь от повторяющегося фрагмента кода, в котором я настраиваю регистратор во многих классах.
Я хотел бы иметь класс, в котором 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
свойство для каждого класса?
Ответ №1:
Вместо того, чтобы создавать экземпляр глобального в модуле и затем пытаться получить к нему доступ, вы могли бы просто использовать 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