Моносостояние (Класс Борга) Каким образом все свойства одного экземпляра становятся свойствами других?
Объясните, пожалуйста, как это работает?
class Borg:
_shared_state = {}
def __init__(self):
self.__dict__ = self._shared_state
Каким образом все свойства одно экземпляра становятся свойствами других? Здесь ведь каждый раз словарю аттрибутов экземпляра класса при инициализации должен присваиваться пустой словарь, а получается наоборот, не понимаю :(
Ответы (2 шт):
Инициализируется словарь при создании класса, а не экземпляра класса. При создании экземпляра всем экземплярам присваивается ссылка на один и тот же словарь, с которым и работают в итоге все экземпляры.
Вот эта часть выполняется сразу, когда интерпретатор встречает объявление класса:
class Borg:
_shared_state = {}
А эта - при создании каждого экземпляра класса:
def __init__(self):
self.__dict__ = self._shared_state
Проверим, что ссылка получается на один и тот же объект:
class Borg:
_shared_state = {}
print(id(_shared_state))
def __init__(self):
self.__dict__ = self._shared_state
print(id(self.__dict__))
a = Borg()
b = Borg()
c = Borg()
Вывод:
140386153522520
140386153522520
140386153522520
140386153522520
Тут есть ещё одна тонкость. Когда выполняется строка:
self.__dict__ = self._shared_state
То вроде бы должно браться значение переменной _shared_state из экземпляра класса (ключевое слово self). Но своей такой переменной у экземпляра нет, поэтому берётся "статическая" переменная - из описания самого класса. Если в дальнейшем что-то присвоить переменной self._shared_state, то она перестанет указывать на статический объект класса и заживёт собственной жизнью, это нужно знать.
Так получается потому что. Объект класса _shared_state ссылается на одну ячейку памяти(допустим "а") и когда мы пишем:
def __init__(self):
self.__dict__ = self._shared_state
то у нас объект ЭК __dict__ ссылается на тот же объект в памяти компьютера, то есть (как я писал ранее) в нашем случае объект "а".
Это получается потому что мы self.__dict__ присваиваем не значение атрибута _shared_state, а лишь ссылку на объект в памяти компьютера в которой он хранится, а как мы знаем если мы присваиваем одной переменной ссылку на другую переменную, то эти две переменные всегда будут хранить одинаковые значения, пока ссылка на объект в памяти не будет удалена.
Почитать подробнее про память ПК можно stackoverflow или habr