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

时间:2018-05-25 17:51:17

标签: python class oop init super

我理解super().__init__()的概念与继承有关,我看到init内的参数代码。但是,我遇到了一个代码示例:

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

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

1 个答案:

答案 0 :(得分:1)

这是super()打算工作的原始方式:

super(Maze, self).__init__()

这也是它在Python 2中运行的唯一方法。

那么,为什么这些论点?

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

实际上做了什么?

super(Maze, self).__init__必须确定type(self)从中提取MRO,即类从彼此继承的顺序。

然后,在该列表中,它找到位于Maze之上的类,并在该类或其上方的任何类中查找__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代码总是使用当前类和self作为参数,因此Python 3通过提供一个知道你想要的魔法super()来使它更容易。