Я работал над проблемой из двух частей:
1) Создайте класс Foo (), который создает уникальные экземпляры на основе одного переданного значения «x». Если пытаются создать несколько экземпляров с одним и тем же значением «x», то следует оставить только первый.
Foo () работает правильно.
2) Создайте класс Bar (), унаследованный от Foo (). Он должен выполнять ту же работу, что и Foo () (только для уникальных элементов), но допускать использование двух переменных, «x» и «y».
Вот что странно. У меня работает часть 1. Я работал над второй частью, когда - Shazam! - часть 2, похоже, работает. Однако я понятия не имею, почему. Я не думал, что у меня закодирована часть проверки «y», но похоже, что все работает. Может ли кто-нибудь взглянуть на это и сказать мне, почему часть 2 работает?
Из объектов f1 - f5 есть два уникальных предмета.
Из объектов f6 - f13 есть четыре уникальных предмета.
Всего: 6 уникальных предметов, что я получаю, когда запускаю его. Но я понятия не имею, как выполняется уникальность, основанная на переданном параметре 'y'.
Мой код:
seenx = {}
# seeny = {}
class Foo(object):
def __init__(self, x):
self.x = x
@classmethod
def new(cls, x):
if x not in seenx:
seenx[x] = cls(x)
return seenx[x]
f1 = Foo.new(10)
f2 = Foo.new(10)
f3 = Foo.new(20)
f4 = Foo.new(10)
f5 = Foo.new(20)
s = {f1, f2, f3, f4, f5}
for i in s:
print(i)
class Bar(Foo):
def __init__(self, x, y):
super().__init__(x)
self.y = y
@classmethod
def new2(cls, x, y):
return super().new(x).new(y)
f6 = Bar.new2(10, 'abc')
f7 = Bar.new2(10, 'abc')
f8 = Bar.new2(20, 'xyz')
f9 = Bar.new2(10, 'abc')
f10 = Bar.new2(20, 'xyz')
f11 = Bar.new2(10, 'def')
f12 = Bar.new2(20, 'ghi')
f13 = Bar.new2(20, 'ghi')
s2 = {f6, f7, f8, f9, f10, f11, f12, f13}
for i in s2:
print(i)
И вывод:
<__main__.Foo object at 0x0D704F30>
<__main__.Foo object at 0x0D704EF0>
<__main__.Foo object at 0x0D722090>
<__main__.Foo object at 0x0D722030>
<__main__.Foo object at 0x0D722050>
<__main__.Foo object at 0x0D722070>
Ты прав. Можете ли вы указать мне правильное направление?





Вот класс, который отслеживает этот экземпляр с помощью метода __new__.
class Foo:
_instances = {}
def __new__(cls, *args):
if args not in cls._instances:
cls._instances[args] = super().__new__(cls)
return cls._instances[args]
def __init__(self, x):
self.x = x
class Bar(Foo):
_instances = {}
def __init__(self, x, y):
super().__init__(x)
self.y = y
TypeError: super .__ new __ (Foo): Foo не является подтипом super
@MarkS Просто опечатка, попробовать исправленную версию?
Ваш подход
Barна самом деле не работает. ПопробуйтеBar.new2(20, 'xyz')иBar.new2(10, 'xyz'). Они оба вернут один и тот же объект, чего не должно быть.