Лучшая практика для регистрации дочерних классов в Python - PullRequest
0 голосов
/ 11 октября 2019

Я хотел бы получить ваши идеи о том, как реализовать хороший код для родительских и дочерних классов, которые должны быть зарегистрированы.

Моя проблема в том, что мне нужно регистрировать атрибуты родительского и дочернего экземпляра при создании, значит, внутри init -функции. Создание дочернего экземпляра также приводит к тому, что его родительский класс регистрирует сообщение. Можно ли регистрировать сообщение только из родительского экземпляра, если он не вызван из дочернего экземпляра?

Это простой пример моей проблемы, заранее спасибо ...

import logging
from uuid import uuid4

logging.basicConfig(format='%(name)s %(levelname)-7s:%(message)s', level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.debug("here")


class A:
    init_log_message = "Instance of P"
    def __init__(self):
        self.id = uuid4()
#        logger = logging.getLogger(__name__)
        logger.error(f"{A.init_log_message}")


class B(A):
    init_log_message = "Instance of C"
    def __init__(self):
        self.id = uuid4()
        super().__init__()
#        logger = logging.getLogger(__name__)
        logger.warning(f"{B.init_log_message}")


b = B()

Вывод на консоль выглядит следующим образом:

__main__ DEBUG  :here
__main__ ERROR  :Instance of P
__main__ WARNING:Instance of C

Сообщение в средней части приходит от родительского класса через команду super (), которую я предполагаю. Как можно избежать этого сообщения?

Спасибо за любую идею или комментарий ...

Ответы [ 2 ]

0 голосов
/ 22 октября 2019

Наконец я нашел способ регистрировать только дочерние экземпляры без какой-либо реакции их родительского экземпляра.

Я поместил эти строки в init -функции, чтобы регистрировать только когда нетребенок существует.

def __init__(self):
    if not SensorBase.__subclasses__():
            logger.debug(f"<{__class__.__name__} Instance created: "
                         f"UUID={self.id}, NAME={self.name}@{self.node}>")
0 голосов
/ 17 октября 2019

Вы можете иметь статическую строку init_log_message в своем классе Parent и переопределить ее в своем классе Child:

import logging

logger = logging.getLogger(__name__)

class Parent:
    init_log_message = "Instance P created"

    def __init__(self):
        logger.debug(self.init_log_message)

class Child(Parent):
    init_log_message = "Instance C created"

if __name__ == "__main__":
    logging.basicConfig(level="DEBUG")
    p = Parent()
    c = Child()

Обратите внимание, что logger больше не является атрибутом класса, так какParent.logger и Child.logger были одинаковыми в вашем примере кода, поэтому я перенес его в качестве атрибута модуля.

...