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

在 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 教程,它并没有涉及到这一点。当我在谷歌上搜索的时候,我发现了不止一种方法。处理这个问题的标准方法是什么?

207458 次浏览

都有

SuperClass.__init__(self, x)

或者

super(SubClass,self).__init__( x )

将工作(我更喜欢第二个,因为它坚持更多的 DRY 原则)。

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

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)

但既然你不应该再用老式的了,我就不会太在意这个了。

Python3只知道新样式类(无论是否从 object派生)。

在 python3.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

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

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

注意,ABC0可能只返回 None-它的目的是就地修改对象。

什么 __new__

还有另一种方法来初始化实例——这是 Python 中不可变类型的子类的唯一方法。因此,如果你想要子类 str或者 tuple或者其他不可变物件,它是必需的。

您可能会认为它是一个 classmethod,因为它获得了一个隐式类参数。但这是 实际上是一种静态方法。因此,您需要使用 cls显式地调用 __new__

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

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')