在 super 和 init 括号内有参数有什么区别.... super().__init__()

What is the difference between having parameters within super and the init parentheses .... super().__init__()

我知道 super().__init__() 的概念与继承有关,我在 init 中看到过带参数的代码。但是,我遇到了一个代码示例:

class Maze(tk.Tk, object):
    def __init__(self):
        super(Maze, self).__init__()

参数现在位于 super 括号内。有什么区别,为什么一个可以用于另一个?谢谢

这是 super() 最初的工作方式:

super(Maze, self).__init__()

这也是它在 Python 2 中起作用的唯一方法。

那么,为什么会有争论?

您想调用 class 的 __init__(),它是 super class 如果 Maze(可能 tk.Tk),绑定到 self。为此,您必须将参数 Mazeself 传递给 super,以便它知道该做什么。

它到底有什么作用?

super(Maze, self).__init__ 必须确定 type(self) 才能从中提取 MRO,即 class 相互继承的顺序。

然后,在该列表中,它找到 Maze 正上方的 class,并在 class 或任何 class 中查找 __init__ ] 它上面。当它找到它时,它将 __init__ init 方法绑定到 self(即修复它的第一个参数,所以你不必传递它)。

您可以自己实现 super 的那个版本。它会是这样的:

class my_super:
    def __init__(self, cls, obj):
        self.cls = cls
        self.obj = obj

    def __getattribute__(self, method_name):
        cls = object.__getattribute__(self, 'cls')
        obj = object.__getattribute__(self, 'obj')
        mro = type(obj).__mro__
        mro_above_cls = mro[mro.index(cls)+1:]
        for super_cls in mro_above_cls:
            if hasattr(super_cls, method_name):
                method = getattr(super_cls, method_name)
                return functools.partial(method, self)

请注意,您根本不必从方法中调用它。你可以这样做:

class A:
    def f(self):
        print('A')


class B(A):
    def f(self):
        print('B')

a = A()
b = B()

super(B, b).f()      # prints: A
my_super(B, b).f()   # prints: A

没有参数的版本呢?

super(Maze, self).__init__() 非常明确,但几乎所有 Python 代码总是使用当前 class 和 self 作为参数,因此 Python 3 通过提供知道你想要什么的魔法super()