super().__init__(*args, **kwargs) 是做什么的?

What does super().__init__(*args, **kwargs) do?

我不知道 super().__init__(*args, **kwargs) 在这里做什么。

class B(type):
    def __init__(self, *args, **kwargs):
        self.a = 'a'
        super().__init__(*args, **kwargs)


class A(metaclass=B):
    pass

据我所知,super() returns 一个超级实例 class 跟踪 MRO 中的当前位置。在 super 实例上调用方法时,super 在 MRO 中查找下一个 class 并调用该 class.

上的方法
B.__mro__
(<class '__main__.B'>, <class 'type'>, <class 'object'>)

super().__init__(*args, **kwargs)调用__init__方法,是什么意思?

如果我删除它

class B(type):
    def __init__(self, *args, **kwargs):
        self.a = 'a'


class A(metaclass=B):
    pass

初始化Aclass

x=A()
x.a
'a'

实例x属于Aclass仍然拥有属性a,效果相同。

这是一个快速示例

>>> class A:
        def __init__(self, a="a",*argv,**karg):
            super().__init__(*argv,**karg)
            self.a=a

    
>>> class B(A):
        def __init__(self, b="b",*argv,**kargv):
            super().__init__(*argv,**kargv)
            self.b=b

        
>>> class Bad(B):
        def __init__(self,b="bad",*arg,**kargv):
            self.b=b

        
>>> b=B()
>>> b.a
'a'
>>> b.b
'b'
>>> bad=Bad()
>>> bad.b
'bad'
>>> bad.a
Traceback (most recent call last):
  File "<pyshell#220>", line 1, in <module>
    bad.a
AttributeError: 'Bad' object has no attribute 'a'
>>> 

这里 A 是我们的基础 class,我们希望它的任何子class 具有 A 的所有特征加上任何额外的子class有,然后要添加新功能,我们只是 subclass 它并使用 super 将 A 知道如何做的部分委托给我们的父级,所以我们不重复那些部分,这里 B是坚持这个原则的subclass

现在 Bad 是一个子class,它不遵守这个原则,因此不会有任何在 A 父级构造中设置的功能,因此它不会设置其 .a 属性,因为它拒绝通过不通过 super.

调用其父构造函数来进行合作

一些相关的讲解视频: Raymond Hettinger - Super considered super! - PyCon 2015