python 中超级方法的隐含参数

Implied parameters for super method in python

在一门关于多重继承的课程中,我遇到了这段漂亮的代码。

class First(object):
    def __init__(self):
        super(First, self).__init__()
        print("first")

class Second(object):
    def __init__(self):
        super(Second, self).__init__()
        print("second")

class Third(Second,First):
    def __init__(self):
        super(Third, self).__init__()
        print("third")

Third();

输出:

first
second
third

我有点害怕,所以我开始研究为什么这个东西能起作用。我发现 a lovely article about this matter 很好地解释了 super 背后的机制。

然后我开始玩代码,发现大部分代码其实都是多余的。我一步一步地修剪东西,直到只剩下这个可怜的骨架。

class First():
    def __init__(self):
        super().__init__()
        print("first")

class Second():
    def __init__(self):
        super().__init__()
        print("second")

class Third(Second,First):
    def __init__(self):
        super().__init__()
        print("third")

Third();

这会产生完全相同的输出。现在对于 object,我知道这可以省略,因为所有 classes 都派生自基数 class object。那里没有问题。但是我不太明白传递给 super 方法的参数背后的含义。所以我做了这个最后的调整来检查这是否也有效:

class First():
    def __init__(self):
        super().__init__()
        print("first")

class Second():
    def __init__(self):
        super().__init__()
        print("second")

class Third(Second,First):
    def __init__(self):
        super(self).__init__()
        print("third")

Third();

输出:

TypeError: super() argument 1 must be type, not Third

我可以理解在这种情况下self指的是Third。在 super(Third,self) 的情况下,Third 指的是 class ,这足以作为我想的类型。那么在调用 super 方法时,总是隐含所有这些冗余部分是否正确?除了我已经找到的 link 之外,还有人有关于这些机制的一些很酷的文档吗?似乎调用它们的顺序与列出 class 参数的顺序相反。 反转为 class Third(First,Second) 给出输出:

second
first
third

如果对此事有更多了解,我们将不胜感激。

您的顶级示例代表 super 的第一个实现。该实现在以后的版本中变得更加智能,因此您应该使用第二个示例。另一个只是过时了。如果您使用多重继承,您可以将正确的父 class 传递给 super,但这是一种特殊情况。

super 被创建时,在 Python 2.x 的日子里,它的参数(class 你想要“超级”的,以及您调用该方法的实例)需要明确。

从语言的角度来看,super是一个没有特殊处理的普通调用。

在创建 Python 3 时,人们同意调用超 classes 中的方法很常见,因此值得特殊的语言处理,因此它是: 在 Python 3 中,调用 super 变得非常特殊,它由编译器本身处理(不是语言 运行time - 编译器,运行s,虽然在一种透明的方式,在与实际 运行 程序完全分开的循环中)。编译器安排创建一个隐藏的局部变量 - 它称为 __class__,而无参数 super() 调用实际上是 super(__class__, self)__class__ 指向在外部 class 语句体中定义的 class。这种机制实际上是在其他情况下发生的更“幕后发生的神奇事情”之一,非常明确,Python。

填入参数的 super() 的旧的、明确的形式当然仍然有效。

发现其中一些“隐形”机制的一个好方法是尝试将无参数 super 调用放在普通函数中,而不是方法中:尝试时您会看到早期错误运行代码。