#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)
, это происходит практически на всех языках, иногда предоставляемых в немного другом формате, но это должно произойти, чтобы передать любые требуемые аргументы базовому классу