我有一个班级:
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
编写所有这些样板代码似乎很愚蠢,例如将所有args从B
的Ctor传递到内部调用A
的ctor,从那以后每次更改{{{ 1}}的ctor必须应用于A
代码中的其他两个地方。
我猜python有一些习惯用来处理我不知道的这种情况。你能指出我正确的方向吗?
我最好的预感,就是为A创建一种Copy-Ctor,然后将B的代码改为
B
这符合我的需要,因为我总是在给出父类的实例时创建子类,虽然我不确定它是否可能......
答案 0 :(得分:20)
考虑到参数可以通过名称或位置传递,我会编码:
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
答案 1 :(得分:7)
编辑:基于马特的建议,并解决gnibbler关注的问题,即位置论证方法;您可以检查以确保指定了附加的子类特定参数 - 类似于Alex's answer:
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's 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
答案 2 :(得分:2)
在传递给__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
答案 3 :(得分:0)
你想要这样的东西吗?
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)