避免在子类中指定所有参数

ola*_*ndo 19 python constructor arguments subclass

我有一节课:

class A(object):
    def __init__(self,a,b,c,d,e,f,g,...........,x,y,z)
        #do some init stuff
Run Code Online (Sandbox Code Playgroud)

我有一个子类需要一个额外的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
Run Code Online (Sandbox Code Playgroud)

编写所有这些样板代码似乎是愚蠢的,例如将所有args从BCtor传递到内部调用Actor,因为那时对Actor的每次更改都必须应用于B代码中的其他两个位置.

我猜python有一些习惯用来处理我不知道的这种情况.你能为我指出正确的方向吗?

我最好的预感是,有一种用于A的Copy-Ctor,然后将B的代码更改为

class B(A):
     def __init__(self,instanceOfA,W):
         A.__copy_ctor__(self,instanceOfA)
         self.__W=W
Run Code Online (Sandbox Code Playgroud)

这符合我的需要,因为我总是在给出父类的实例时创建子类,虽然我不确定它是否可能......

Ale*_*lli 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
Run Code Online (Sandbox Code Playgroud)


ber*_*nie 7

编辑:基于马特的建议,并解决gnibbler关注的位置论证方法; 您可以检查以确保指定了附加的子类特定参数 - 类似于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
Run Code Online (Sandbox Code Playgroud)

原始答案:
Matt的答案相同,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
Run Code Online (Sandbox Code Playgroud)