Почему моя реализация singleton не работает в Python? - PullRequest
0 голосов
/ 07 мая 2020

Ниже представлена ​​попытка реализовать Singleton в python 3, но, похоже, она не работает. Когда я создаю экземпляр, _instance всегда None, и оба экземпляра (a и b) имеют разные адреса в памяти - почему?

class Singleton(object):
    _instance = None

    def __call__(self, *args, **kwargs):
        if self._instance is None:
            self._instance = super().__call__(*args, **kwargs)
        return self._instance

    def __init__(self, *args, **kwargs):
        print(self._instance, self)


a = Singleton()
b = Singleton()

Результат:

(None, <__main__.Singleton object at 0x7f382956c190>)
(None, <__main__.Singleton object at 0x7f382956c410>)

1 Ответ

1 голос
/ 07 мая 2020

Метод __call__ не такой, как вы думаете. Он предназначен для того, чтобы экземпляры классов вызывались как функции:

class A:
    def __call__(self):
        print("called")

a = A() # prints nothing
a() # prints "called"

То, что вы ищете, - это метод __new__:

Вызывается создайте новый экземпляр класса cls.

Вы можете написать синглтон следующим образом (очень похоже на то, что вы написали):

class Singleton(object):
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance

    def __init__(self, *args, **kwargs):
        print(self._instance, self)


a = Singleton()
b = Singleton()

Теперь вывод:

<__main__.Singleton object at 0x7f149bf3cc88> <__main__.Singleton object at 0x7f149bf3cc88>
<__main__.Singleton object at 0x7f149bf3cc88> <__main__.Singleton object at 0x7f149bf3cc88>
...