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

2024-05-14 18:06:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一节课:

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

编写所有这些锅炉盘代码似乎是愚蠢的,例如将所有参数从B的Ctor传递到A的Ctor的内部调用,从那时起,对A的Ctor的每次更改都必须应用到B代码中的其他两个位置。

我猜python有一些习惯用法来处理这些我不知道的情况。你能告诉我正确的方向吗?

我最好的预感是,为a设置一个拷贝Ctor,然后将B的代码更改为

class B(A):
     def __init__(self,instanceOfA,W):
         A.__copy_ctor__(self,instanceOfA)
         self.__W=W

这将适合我的需要,因为我总是在给定父类的实例时创建子类,尽管我不确定是否可能。。。


Tags: 代码self参数objectinitdefsome子类
3条回答

编辑:基于Matt的建议,为了解决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

考虑到参数可以按名称或位置传递,我将编写代码:

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

在传递给__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

相关问题 更多 >

    热门问题