что __init__ одного класса делает в теле другого класса?

#python #python-3.x #oop #singleton

#python #python-3.x #ооп #синглтон

Вопрос:

 class Borg:
    """Borg pattern making the class attributes global"""
    _shared_data = {} # Attribute dictionary

    def __init__(self):
        self.__dict__ = self._shared_data # Make it an attribute dictionary

        
class Singleton(Borg): #Inherits from the Borg class
    """This class now shares all its attributes among its various instances"""
    # This essentially makes the singleton objects an object-oriented global variable

    def __init__(self, **kwargs):
        Borg.__init__(self)  # WHAT DOES THIS DO? Why is borg initialized with the self of this class?
        self._shared_data.update(kwargs) # Update the attribute dictionary by inserting a new key-value pair 

    def __str__(self):
        return str(self._shared_data) # Returns the attribute dictionary for printing
  

Borg.__init__(self) Что это делает? Что borg инициализируется с помощью self этого класса?

Комментарии:

1. Экземпляр вашего Singleton класса является экземпляром Borg , и для корректной инициализации Borg экземпляра существует __init__ метод Borg . Так что, так или иначе, это хорошая идея, чтобы он был вызван.

Ответ №1:

Когда вы создаете объект производного класса, Python вызывает только __init__ специальный метод для самого производного класса. Если классы-предки требуют инициализации, программист производного класса должен явно вызывать __init__ эти классы.

То, что вы показываете, — это старая идиома, совместимая с Python 2: Borg.__init__ это несвязанный метод инициализации Borg класса. Если вы вызываете его, вы должны передать ему объект в качестве первого параметра, потому что в Python, если a это объект из A класса, имеющего m метод без параметров, a.m() это то же самое, что A.m(a) — если есть параметры, они просто придут после объекта.

В этом случае и при условии Python 3 наиболее идиоматичным способом было бы:

 def __init__(self, **kwargs):
    super().__init__()  # exactly the same as Borg.__init__(self)
    ...
  

Ответ №2:

Только «дочерний инициализированный» будет выполнен.

Итак, в вашем случае, если вы вызываете Singleton, только одноэлементный init будет выполнен.

Ответ №3:

создание экземпляра Singleton класса, подобного этому mySingleton = Singleton(someArgs) , вызовет конструктор, def __init__(self, **kwargs): инициализирующий новый экземпляр вашего класса. первое, что инициализируется блоком кода инициализации, — это вызвать инициализацию базового класса Borg путем вызова Borg.__init__(self) , это происходит практически на всех языках, иногда предоставляемых в немного другом формате, но это должно произойти, чтобы передать любые требуемые аргументы базовому классу