У меня есть класс:
class A(object):
def __init__(self,a,b,c,d,e,f,g,...........,x,y,z)
#do some init stuff
И у меня есть подкласс, которому нужен один дополнительный аргумент (последнее W
)
class B(A):
def __init__(self.a,b,c,d,e,f,g,...........,x,y,z,W)
A.__init__(self,a,b,c,d,e,f,g,...........,x,y,z)
self.__W=W
Это кажется немым для написания всего этого шаблонного кода, например, передающий весь args от B
Ctor к внутреннему вызову к A
ctor, с тех пор каждое изменение в A
ctor должен быть применен к двум другим местам в B
код.
Я предполагаю, что Python имеет некоторую идиому для обработки таких случаев, о которых я не знаю. Можно ли указать на меня в правильном направлении?
Моя лучшая догадка, должна иметь своего рода Копию-Ctor для A и затем изменить код B в
class B(A):
def __init__(self,instanceOfA,W):
A.__copy_ctor__(self,instanceOfA)
self.__W=W
Это удовлетворило бы моим потребностям, так как я всегда создаю подкласс при приведении пример родительского класса, Хотя я не уверен, возможно ли это...
Учитывая, что аргументы могут передаваться как по имени, так и по позиции, я бы закодировал:
class B(A):
def __init__(self, *a, **k):
if 'W' in k:
w = k.pop('W')
else:
w = a.pop()
A.__init__(self, *a, **k)
self._W = w
Хотите что-то вроде этого?
class A(object):
def __init__(self, a, b, c, d, e, f, g):
# do stuff
print a, d, g
class B(A):
def __init__(self, *args):
args = list(args)
self.__W = args.pop()
A.__init__(self, *args)
Правка: основанный на предложении Мэтта, и для решения проблемы гнибблера - позиционно-аргументный подход; вы можете проверить, что дополнительный аргумент, специфичный для подкласса, указан - аналогично ответу Алекса :
class B(A):
def __init__(self, *args, **kwargs):
try:
self._w = kwargs.pop('w')
except KeyError:
pass
super(B,self).__init__(*args, **kwargs)
>>> b = B(1,2,w=3)
>>> b.a
1
>>> b.b
2
>>> b._w
3
оригинальный ответ:
.
Та же идея, что и в ответе Мэтта , вместо него используется super()
.
Используйте super()
для вызова метода superclass's __init__()
, а затем продолжайте инициализацию подкласса:
class A(object):
def __init__(self, a, b):
self.a = a
self.b = b
class B(A):
def __init__(self, w, *args):
super(B,self).__init__(*args)
self.w = w