如何初始化基础(超级)类?

时间:2010-09-12 09:43:50

标签: python oop

在Python中,请考虑我有以下代码:

>>> class SuperClass(object):
    def __init__(self, x):
        self.x = x

>>> class SubClass(SuperClass):
    def __init__(self, y):
        self.y = y
        # how do I initialize the SuperClass __init__ here?

如何初始化子类中的SuperClass __init__?我正在关注Python教程,但它没有涵盖这一点。当我在Google上搜索时,我找到了不止一种方法。处理此问题的标准方法是什么?

4 个答案:

答案 0 :(得分:130)

Python(直到版本3)支持“旧式”和新式类。新式类派生自object并且正在使用,并通过super()调用其基类,例如。

class X(object):
  def __init__(self, x):
    pass

  def doit(self, bar):
    pass

class Y(X):
  def __init__(self):
    super(Y, self).__init__(123)

  def doit(self, foo):
    return super(Y, self).doit(foo)

因为python知道旧式和新式类,所以有不同的方法来调用基本方法,这就是为什么你找到了多种方法。

为了完整起见,旧式类使用基类显式调用基本方法,即

def doit(self, foo):
  return X.doit(self, foo)

但是既然你不应该再使用旧式了,我就不会太在意了。

Python 3只知道新式类(无论你是否派生自object)。

答案 1 :(得分:34)

两个

SuperClass.__init__(self, x)

super(SubClass,self).__init__( x )

会起作用(我更喜欢第二个,因为它更符合DRY原则)。

见这里:http://docs.python.org/reference/datamodel.html#basic-customization

答案 2 :(得分:15)

  

如何初始化基础(超级)类?

class SuperClass(object):
    def __init__(self, x):
        self.x = x

class SubClass(SuperClass):
    def __init__(self, y):
        self.y = y

使用super对象确保您在方法解析顺序中获得下一个方法(作为绑定方法)。在Python 2中,您需要将类名称和self传递给super以查找绑定的__init__方法:

 class SubClass(SuperClass):
      def __init__(self, y):
          super(SubClass, self).__init__('x')
          self.y = y

在Python 3中,有一些神奇的东西会使super的参数变得不必要 - 而且作为一个附带好处,它可以更快地运行:

 class SubClass(SuperClass):
      def __init__(self, y):
          super().__init__('x')
          self.y = y

如下所示对父级进行硬编码会阻止您使用协作多重继承:

 class SubClass(SuperClass):
      def __init__(self, y):
          SuperClass.__init__(self, 'x') # don't do this
          self.y = y

请注意__init__ may only return None - 它旨在就地修改对象。

某事__new__

还有另一种初始化实例的方法 - 它是Python中不可变类型的子类的唯一方法。因此,如果您想要继承strtuple或其他不可变对象,则需要它。

您可能认为它是一种类方法,因为它获得了一个隐式类参数。但它是actually a staticmethod。因此,您需要明确地使用__new__致电cls

我们通常会从__new__返回实例,因此如果您这样做,您还需要在基类中通过__new__调用基础super。因此,如果您使用这两种方法:

class SuperClass(object):
    def __new__(cls, x):
        return super(SuperClass, cls).__new__(cls)
    def __init__(self, x):
        self.x = x

class SubClass(object):
    def __new__(cls, y):
        return super(SubClass, cls).__new__(cls)

    def __init__(self, y):
        self.y = y
        super(SubClass, self).__init__('x')

Python 3避开了__new__作为静态方法导致的超级调用的一些奇怪现象,但您仍然需要将cls传递给非绑定__new__方法:

class SuperClass(object):
    def __new__(cls, x):
        return super().__new__(cls)
    def __init__(self, x):
        self.x = x

class SubClass(object):
    def __new__(cls, y):
        return super().__new__(cls)
    def __init__(self, y):
        self.y = y
        super().__init__('x')

答案 3 :(得分:14)

从python 3.5.2开始,您可以使用:

class C(B):
def method(self, arg):
    super().method(arg)    # This does the same thing as:
                           # super(C, self).method(arg)

https://docs.python.org/3/library/functions.html#super