Singleton class без возможности повторной инициализации в Python
Мне нужно сделать класс, который будет работать как Singleton и который должен унаследовать от базового класса. Классов подобных MyClass может быть несколько.
В конце концов, я пришёл к следующему решению:
import random
class Singleton(object):
_instances = {}
def __new__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instances[cls]
class BaseClass(object):
def __init__(self, data):
self.value = random.random()
self.data = data
def asfaa(self):
pass
class MyClass(BaseClass, Singleton):
def __init__(self, data=3):
super().__init__(data)
self.a = random.random()
class MyClass1(BaseClass, Singleton):
def __init__(self, data=3):
super().__init__(data)
self.a = random.random()
inst1 = MyClass(3)
inst2 = MyClass(5)
Всё работает как нужно если def __init__(self, data=3) в MyClass не принимает аргументов и выглядит следующим образом: def __init__(self)
Если же я предоставляю аргументы в __init__ как в примере выше , то получаю следующую ошибку.
line 9, in __new__
cls._instances[cls] = super(Singleton, cls).__new__(cls, *args, **kwargs)
TypeError: object.__new__() takes exactly one argument (the type to instantiate)
Каким образом можно передать аргументы в MyClass и ему подобные? И в чем проблема?
После ответа splash58 удалось получить вот такой вот работающий результат:
import random
class Singleton(object):
_instances = {}
def __new__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__new__(cls)
return cls._instances[cls]
class BaseClass(object):
def __init__(self, data: int):
self.value = random.random()
self.data = data
def asfaa(self):
pass
class MyClass(BaseClass, Singleton):
def __init__(self, data=0):
if not hasattr(self, '_is_initialized'):
super().__init__(data)
self.a = random.random()
self._is_initialized = True
class MyClass1(BaseClass, Singleton):
def __init__(self, data=0):
if not hasattr(self, '_is_initialized'):
super().__init__(data)
self.a = random.random()
self._is_initialized = True
inst = MyClass(1)
print(inst, inst.a, inst.data)
inst1 = MyClass(1234)
print(inst1, inst1.a, inst1.data)
inst2 = MyClass1(123)
print(inst2, inst2.a, inst2.data)
Результат исполнения:
<__main__.MyClass object at 0x7fd702199890> 0.40160478301994584 1
<__main__.MyClass object at 0x7fd702199890> 0.40160478301994584 1
<__main__.MyClass1 object at 0x7fd7021998d0> 0.6368002566047511 123
Ответы (1 шт):
Поскольку Singleton производный класс от Object, вам совсем не надо передавать данные выше, инит в BaseClass их все равно получит. напишите просто
cls._instances[cls] = super(Singleton, cls).__new__(cls)
и после
inst1 = MyClass(3)
inst2 = MyClass(5)
получите
>>> inst1 == inst2
True
>>> inst1.data
5