Избегайте указания всех аргументов в подклассе
У меня есть класс:
class A(object):
def __init__(self,a,b,c,d,e,f,g,...........,x,y,z)
#do some init stuff
И у меня есть подкласс, которому нужен один дополнительный arg (последний 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
Кажется глупым писать весь этот код котельной, например, передавать все аргументы из B
Ctor во внутренний вызов A
ctor, так как тогда каждое изменение на A
ctor должно применяться к двум другим помещается в код B
.
Я предполагаю, что у python есть некоторая идиома для обработки таких случаев, о которых я не знаю. Можете ли вы указать мне в правильном направлении?
Моя лучшая догадка заключается в том, чтобы иметь тип Copy-Ctor для A, а затем изменить B-код на
class B(A):
def __init__(self,instanceOfA,W):
A.__copy_ctor__(self,instanceOfA)
self.__W=W
Это соответствовало бы моим потребностям, поскольку я всегда создавал подкласс, когда мне давали экземпляр класса отца, хотя я не уверен, возможно ли это...
Ответы
Ответ 1
Учитывая, что аргументы могут передаваться либо по имени, либо по положению, я бы code:
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
Ответ 2
Изменить: на основе предложения Мэтта и обратиться к гнибблеру с призывом к позиционно-аргументационному подходу; вы можете проверить, чтобы указать дополнительный аргумент для конкретного подкласса, похожий на ответ Alex:
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
Оригинальный ответ:
Такая же идея, как Matt answer, вместо этого используйте super()
.
Используйте super()
для вызова метода суперкласса __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
Ответ 3
В ситуациях, когда некоторые или все аргументы, переданные в __init__
, имеют значения по умолчанию, может быть полезно избежать повторения подписи __init__
в подклассах.
В этих случаях __init__
может передавать любые дополнительные аргументы другому методу, которые могут перекрывать подклассы:
class A(object):
def __init__(self, a=1, b=2, c=3, d=4, *args, **kwargs):
self.a = a
self.b = b
# …
self._init_extra(*args, **kwargs)
def _init_extra(self):
"""
Subclasses can override this method to support extra
__init__ arguments.
"""
pass
class B(A):
def _init_extra(self, w):
self.w = w
Ответ 4
Вы хотите что-то вроде этого?
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)