super()和Parent类名称之间有什么区别?

发布于 2021-01-29 17:52:56

super()直接使用和直接使用父类名称之间有区别吗?例如:

class Parent:
    def __init__(self):
        print("In parent")
        self.__a=10

class Child(Parent):
    def __init__(self):
        super().__init__()     # using super()
        Parent.__init__(self)  # using Parent class name

c=Child()

是否有内部之间的差异super().__init__()Parent.__init__(self)

关注者
0
被浏览
170
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    这种情况下 不是。但是 通常 ,尤其是当您使用 多重继承时
    ,按照文档中指定 super()
    方法
    委托给 方法解析顺序(MRO)中 的下一个对象


    super([type[, object-or-type]])

    返回将方法调用委托给类型的父级或同级类的 代理对象
    。这对于访问已在类中重写的继承方法很有用。搜索顺序与所使用的顺序相同,getattr()只是类型本身被跳过。

    __mro__ 类型属性列出了getattr()和所使用
    的方法分辨率搜索顺序super()。该属性是动态的,并且在继承层次结构更新时可以更改。

    (…)

    (已复制,添加了黑体字)

    举例来说,您定义了类似的类(从这个问题中借来的,在此更详​​细地讨论了MRO):

    class F:
        def __init__(self):
            print('F%s'%super().__init__)
            super().__init__()
    
    class G: 
        def __init__(self):
            print('G%s'%super().__init__)
            super().__init__()
    
    class H: 
        def __init__(self):
            print('H%s'%super().__init__)
            super().__init__()
    
    class E(G,H):
        def __init__(self):
            print('E%s'%super().__init__)
            super().__init__()
    
    class D(E,F): 
        def __init__(self):
            print('D%s'%super().__init__)
            super().__init__()
    
    class C(E,G): 
        def __init__(self):
            print('C%s'%super().__init__)
            super().__init__()
    
    class B(C,H): 
        def __init__(self):
            print('B%s'%super().__init__)
            super().__init__()
    
    class A(D,B,E): 
        def __init__(self):
            print('A%s'%super().__init__)
            super().__init__()
    

    那么__mro__ofA是:

    A.__mro__ == (A,D,B,C,E,G,H,F,object)
    

    现在,如果调用A(),它将输出:

    A<bound method D.__init__ of <__main__.A object at 0x7efefd8645c0>>
    D<bound method B.__init__ of <__main__.A object at 0x7efefd8645c0>>
    B<bound method C.__init__ of <__main__.A object at 0x7efefd8645c0>>
    C<bound method E.__init__ of <__main__.A object at 0x7efefd8645c0>>
    E<bound method G.__init__ of <__main__.A object at 0x7efefd8645c0>>
    G<bound method H.__init__ of <__main__.A object at 0x7efefd8645c0>>
    H<bound method F.__init__ of <__main__.A object at 0x7efefd8645c0>>
    F<method-wrapper '__init__' of A object at 0x7efefd8645c0>
    <__main__.A object at 0x7efefd8645c0>
    

    因此,这意味着 A和尝试 获得__init__ 该上下文 时:

    • super().__init__AD.__init__;
    • super().__init__DB.__init__;
    • super().__init__BC.__init__;
    • super().__init__CE.__init__;
    • super().__init__EG.__init__;
    • super().__init__GH.__init__;
    • super().__init__HF.__init__; 和
    • super().__init__Fobject.__init__

    因此请注意,super()本身 并不 委托给父母
    。例如,super()ofDBandB不是of的超类D,因此它实际上 取决于对象的类型 (而不取决于类)。

    现在,如果为D__mro__则为:

    D.__mro__ = (D,E,G,H,F,object)
    

    如果构造一个a,D我们得到:

    D<bound method E.__init__ of <__main__.D object at 0x7efefd864630>>
    E<bound method G.__init__ of <__main__.D object at 0x7efefd864630>>
    G<bound method H.__init__ of <__main__.D object at 0x7efefd864630>>
    H<bound method F.__init__ of <__main__.D object at 0x7efefd864630>>
    F<method-wrapper '__init__' of D object at 0x7efefd864630>
    

    因此 ,在D的上下文中 认为:

    • super().__init__DE.__init__;
    • super().__init__EG.__init__;
    • super().__init__GH.__init__;
    • super().__init__HF.__init__; 和
    • super().__init__Fobject.__init__

    因此,这里 super()D导致E(对于__init__这是 不是在上下文中的相同A



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看