У меня есть набор определенных c определенных классов (скажем, цветные тубы) и общий c класс (скажем, туба). Если создается экземпляр класса generi c, он может вернуть указанный класс c. Я справился с этим, переопределив метод __new__
класса generi c, который проверяет ввод и возвращает соответствующий экземпляр класса.
Это работает для создания объекта, например, я могу сказать
tuba = Tuba('red')
type(tuba) # will give 'RedTuba'
Однако, если я пытаюсь скопировать мою тубу, Python возвращает TypeError
, говорящее, что __new__
пропускает 1 обязательный аргумент. Я не совсем уверен, что понимаю, как __new__
должен использоваться правильно в этой ситуации.
Как мне реализовать __new__
в этом случае, чтобы он работал правильно?
from copy import copy
class Instrument:
def __init__(self, kind):
self.kind = kind
class RedTuba(Instrument):
# note: RedTuba cannot be derived from Tuba since this is an
# abstract example on the actual case I'm having trouble with
def __init__(self):
super().__init__(kind='special-red-tuba')
class Tuba(Instrument):
def __new__(cls, color):
if color == 'red':
return RedTuba.__new__(RedTuba)
return super().__new__(cls)
def __init__(self, color):
super().__init__(kind='{}-tuba'.format(color))
r = Tuba('red')
copy(r) # this works
v = Tuba('violet')
copy(v) # this does not work
Полученная ошибка
Traceback (most recent call last):
File "creation.py", line 28, in <module>
copy(v)
File "/Users/jul/Envs/latest/lib/python3.7/copy.py", line 106, in copy
return _reconstruct(x, None, *rv)
File "/Users/jul/Envs/latest/lib/python3.7/copy.py", line 274, in _reconstruct
y = func(*args)
File "/Users/jul/Envs/latest/lib/python3.7/copyreg.py", line 88, in __newobj__
return cls.__new__(cls, *args)
TypeError: __new__() missing 1 required positional argument: 'color'