Почему копируется синглтон? Помогите пожалуйста решить проблему. Я пытаюсь использовать синглтон:class World(object): def __new__(cls,*dt,**mp): if cls.obj is None: cls.obj = object.__new__(cls,*dt,**mp) return cls.obj def __init__(self, name, boss): self.boss = boss self.name = name World.quantity += 1 obj = None quantity = 0 def __str__(self): return str(self.__class__.__name__) + ': ' + str(self.__dict__) Далее создаю 2 объекта:world1 = World('old', boss='demiurg') world2 = World('new', boss='mr. bin') После запуска ожидаю получить один объект с атрибутом dimiurg. Но получаю 2 объекта с атрибутом mr.bin:kalinin@kalinin ~/python/boats2 $ python index2.py World: {'name': 'new', 'boss': 'mr. bin'} World: {'name': 'new', 'boss': 'mr. bin'} worlds quantity: 2 Непонятно почему: 1. получаются два объекта вместо одного 2. объект имеет атрибут mr.bin, ведь в первую очередь создаётся объект с атрибутом demiurg, а остальные объекты должны быть ссылками на него
Проблема здесь в том, что у вас метод __new__ возвращает новый объект при каждом вызове, даже если объект уже был создан. Вместо этого, вам нужно изменить метод __new__ так, чтобы он возвращал существующий объект, а не создавал новый.
Вот исправленный код:
class World(object): obj = None quantity = 0 def __new__(cls, *args, **kwargs): if cls.obj is None: cls.obj = object.__new__(cls) return cls.obj def __init__(self, name, boss): if not hasattr(self, 'boss'): self.boss = boss self.name = name World.quantity += 1 def __str__(self): return str(self.__class__.__name__) + ': ' + str(self.__dict__) world1 = World('old', boss='demiurg') world2 = World('new', boss='mr. bin') print(world1) print(world2) print(f'worlds quantity: {World.quantity}')
Теперь при создании объекта world2 вы получите ссылку на уже существующий объект world1 с атрибутом demiurg.
Проблема здесь в том, что у вас метод __new__ возвращает новый объект при каждом вызове, даже если объект уже был создан. Вместо этого, вам нужно изменить метод __new__ так, чтобы он возвращал существующий объект, а не создавал новый.
Вот исправленный код:
class World(object):obj = None
quantity = 0
def __new__(cls, *args, **kwargs):
if cls.obj is None:
cls.obj = object.__new__(cls)
return cls.obj
def __init__(self, name, boss):
if not hasattr(self, 'boss'):
self.boss = boss
self.name = name
World.quantity += 1
def __str__(self):
return str(self.__class__.__name__) + ': ' + str(self.__dict__)
world1 = World('old', boss='demiurg')
world2 = World('new', boss='mr. bin')
print(world1)
print(world2)
print(f'worlds quantity: {World.quantity}')
Теперь при создании объекта world2 вы получите ссылку на уже существующий объект world1 с атрибутом demiurg.