如何初始化基类(超级类)? Python中的P>,请考虑我有以下代码: 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?

如何初始化基类(超级类)? Python中的P>,请考虑我有以下代码: 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?,python,oop,Python,Oop,如何初始化子类中的超类\uuuu init\uuuu?我正在学习Python教程,但它没有涵盖这一点。当我在谷歌上搜索时,我发现了不止一种方法。处理这个问题的标准方法是什么?两者都有 SuperClass.__init__(self, x) 或 将工作(我更喜欢第二个,因为它更坚持干燥的原则) 请参见此处:Python(直到版本3)支持“旧样式”和新样式的类。新样式类是从object派生的,是您正在使用的,并通过super()调用它们的基类,例如 class X(object): def

如何初始化子类中的
超类\uuuu init\uuuu
?我正在学习Python教程,但它没有涵盖这一点。当我在谷歌上搜索时,我发现了不止一种方法。处理这个问题的标准方法是什么?

两者都有

SuperClass.__init__(self, x)

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

请参见此处:

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只知道新样式的类(无论您是否从
对象派生)。

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

如何初始化基类(超级类)? 使用
super
对象确保获得方法解析顺序中的下一个方法(作为绑定方法)。在Python 2中,需要将类名和
self
传递给super以查找绑定的
\uuuuu init\uuuu
方法:

 class SubClass(SuperClass):
      def __init__(self, y):
          super(SubClass, self).__init__('x')
          self.y = y
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')
在Python3中,有一个小小的魔法使得
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
请注意-它旨在就地修改对象

一些东西
\uuu新的\uuuu
还有另一种初始化实例的方法——这是Python中不可变类型子类的唯一方法。因此,如果您想要子类化
str
tuple
或另一个不可变对象,则需要使用它

您可能会认为它是一个classmethod,因为它得到一个隐式类参数。但这是一个错误。因此,您需要使用
cls
显式地调用
\uuuu new\uuuu

我们通常从
\uuuuuu new\uuuuu
返回实例,因此如果返回,还需要在基类中通过
super
调用基类的
\uuuuuuuu new\uuuu
。因此,如果您同时使用这两种方法:

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')
Python3稍微回避了由于
\uuuu new\uuuu
是一个静态方法而导致的超级调用的奇怪之处,但是您仍然需要将
cls
传递给非绑定的
\uu new\uu
方法:

 class SubClass(SuperClass):
      def __init__(self, y):
          super(SubClass, self).__init__('x')
          self.y = y
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')

错。super仅适用于新样式类,并且是使用新样式类时调用基的唯一正确方法。此外,还需要使用旧样式构造显式传递“self”。@Ivo-OP在示例中给出了一个新样式类,讨论新样式和旧样式之间的区别没有什么意义,因为任何人都不应该再使用旧样式。我给出的链接(到Python文档)表明,调用超类
\uuuuu init\uuuu
有不止一种“正确”的方法。