Хорошо, чтобы перейти к этому болезненно подробно:
class Singleton:
неявно наследуется от Object
, потому что в python все является объектом.
instance = None
читается только во время загрузки модуля и устанавливает переменную уровня класса instance
равной None
один раз , но может быть перезаписана отдельными экземплярами класса Singleton
.
def __new__(cls):
if cls.instance is None:
cls.instance = super().__new__(cls)
return cls.instance
(Во-первых, я думаю, что это странно, что они помещают туда "cls", я знаю, почему они это сделали, потому что это относится к классу в целом , а не к конкретному экземпляруэтот класс. Но, это может сбивать с толку, поэтому кто-то, кто не знает, на что они смотрят. В любом случае ...)
__new__
- это магическая функция, которая вызывается до __init__
, чтопримерно аналогично выделению места для нового экземпляра класса.Здесь cls.instance
был установлен на None
при загрузке модуля, и поэтому каждый раз, когда создается новый Singleton
, этот тест проводится.Поскольку cls.instance
устанавливается при первом создании Singleton
, super().__new__(cls)
также вызывается только один раз .Суперкласс Singleton
- это Object
.Таким образом, поведение super().__new__(cls)
в точности соответствует ожидаемому для любого другого создаваемого вами класса.
Если вы создаете второй (или третий / четвертый / пятый ...) экземпляр Singleton
тогда этот super().__new__(cls)
не будет вызван.Вместо этого возвращается переменная уровня класса instance
, означающая, что новые экземпляры Singleton
не могут быть созданы .
Когда вы печатаете экземпляры Singleton
, вы можете увидетьадрес памяти 0x10dbc0f60
одинаков для обоих «экземпляров», потому что cls.instance
возвращается во время __new__
, которое можно рассматривать как время выделения памяти до вызова __init__
.
Этоэто хороший способ сделать шаблон Singleton, потому что теперь для создания одноэлементного класса все, что вам нужно сделать, это наследовать от Singleton
, и тяжелая работа уже сделана.Вы продолжаете и используете __init__
, как обычно, и не беспокоитесь об этом.Каждый раз, когда вы создаете «новый» экземпляр этого класса, вы получаете тот же экземпляр обратно.Полностью за кадром.
Это довольно продвинутые вещи, но посмотрите, как это просто.Питон самый лучший!