Вы превысили __call__
, поэтому A.__new__
не вызывается, если self.__instance
не None
.Нет вызова A.__new__
, нет неявного вызова A.__init__
.
Метакласс __init__
метод не становится __init__
методом A
;он вызывается, когда выполняется оператор class
.Таким образом, в этом случае, после того, как
class A(metaclass=Singleton):
pass
A.__instance
будет существовать, инициализируется None
Singleton.__init__
.
Учитывая ваше определение A
, A()
оценивается какSingleton.__call__(A)
, с A
привязанным к self
.Если A.__instance
по-прежнему None
, то вызывается type.__call__(A)
, который вызывает A.__new__
, создавая новый экземпляр.
Использование модуля, который juanpa.arrivillaga и я намекаем назаменяет класс типа
class A(metaclass=Singleton):
x = 3
def __init__(self, y):
self.y = 9
def combine(self):
return self.x + self.y
на модуль A.py
, который выглядит как
x = 3
def init(val):
global y
y = val
def combine():
return x + y
Переменные и методы экземпляра становятся функциями верхнего уровня и глобальными переменными модуля.Нет реальной разницы между атрибутом класса и атрибутом экземпляра, если существует только один экземпляр.A.init
должен быть вызван напрямую.Если он не принимает никаких аргументов, вы можете опустить его и поместить код на верхний уровень, где он вызывается при импорте.(Не существует параметризованной формы импорта, в которой import A(3)
импортировал бы A.py
и передал бы 3 в качестве аргумента в код верхнего уровня.)