super() 和 Parent 类名有什么区别? [英] What's the difference between super() and Parent class name?

查看:33
本文介绍了super() 和 Parent 类名有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

class 父类:def __init__(self):打印(在父级")self.__a=10类孩子(父母):def __init__(self):super().__init__() # 使用 super()Parent.__init__(self) # 使用父类名c=孩子()

super().__init__()Parent.__init__(self) 有内部区别吗?

解决方案

不在这种情况下.但是一般,尤其是当您使用多重继承时,super() 委托给方法中的下一个对象文档中指定的解决顺序 (MRO):

<块引用>

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

返回一个代理对象,它将方法调用委托给父对象或兄弟类的类型.这对于访问继承的方法很有用已在类中被覆盖.搜索顺序与此相同getattr() 使用,除了类型本身被跳过.

类型的 __mro__ 属性列出了 getattr()super()<使用的方法解析搜索顺序/代码>.属性是动态的,并且可以在继承层次结构发生变化时发生变化更新了.

(...)

(复制,加粗)

例如,您定义了类似的类(借自 这个问题,其中更详细地讨论了 MRO):

F 类:def __init__(self):打印('F%s'%super().__init__)super().__init__()G类:def __init__(self):打印('G%s'%super().__init__)super().__init__()H类:def __init__(self):打印('H%s'%super().__init__)super().__init__()E(G,H)类:def __init__(self):打印('E%s'%super().__init__)super().__init__()D类(E,F):def __init__(self):打印('D%s'%super().__init__)super().__init__()C(E,G)类:def __init__(self):打印('C%s'%super().__init__)super().__init__()B(C,H)类:def __init__(self):打印('B%s'%super().__init__)super().__init__()A级(D、B、E):def __init__(self):打印('A%s'%super().__init__)super().__init__()

那么A__mro__就是:

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

现在如果我们调用A(),它会打印:

A>0x7efefd8645c0处的<__main__.A对象>的D<绑定方法B.__init__>B<绑定方法C.__init__ of <__main__.A object at 0x7efefd8645c0>>0x7efefd8645c0处的<__main__.A对象>的C<绑定方法E.__init__>0x7efefd8645c0处的<__main__.A对象>的E<绑定方法G.__init__>0x7efefd8645c0处的<__main__.A对象>的G<绑定方法H.__init__>0x7efefd8645c0处的<__main__.A对象>的H<绑定方法F.__init__>F<method-wrapper '__init__' of A object at 0x7efefd8645c0><__main__.A 对象在 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() 本身不会委托给父级.例如 Dsuper()BB 不是 D<的超类/code>,所以它确实取决于对象的类型(而不是类).

现在在 D 的情况下,__mro__ 是:

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

如果我们构造一个 D 但是我们得到:

D>0x7efefd864630处<__main__.D对象的<绑定方法G.__init__>>0x7efefd864630处<__main__.D对象的G<绑定方法H.__init__>>0x7efefd864630处<__main__.D对象的H<绑定方法F.__init__>>位于 0x7efefd864630 处的 D 对象的 F<method-wrapper '__init__'>

所以D的上下文中,它认为:

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

所以这里Dsuper()导致E(对于__init__)A 的上下文中不一样.

Is there a difference between using super() and using the parent class name directly? For example:

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()

Is there internally a difference between super().__init__() and Parent.__init__(self)?

解决方案

Not in this case. But in general, and especially when you use multiple inheritance, super() delegates to the next object in the Method Resolution Order (MRO) as is specified in the documentation:

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

Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The search order is same as that used by getattr() except that the type itself is skipped.

The __mro__ attribute of the type lists the method resolution search order used by both getattr() and super(). The attribute is dynamic and can change whenever the inheritance hierarchy is updated.

(...)

(copied, boldface added)

Say for instance you define classes like (borrowed from this question, where the MRO is discussed in more detail):

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__()

Then the __mro__ of A is:

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

Now if we call A(), it prints:

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>

so it means that in the context of A and when trying to obtain __init__ that:

  • super().__init__ of A is D.__init__;
  • super().__init__ of D is B.__init__;
  • super().__init__ of B is C.__init__;
  • super().__init__ of C is E.__init__;
  • super().__init__ of E is G.__init__;
  • super().__init__ of G is H.__init__;
  • super().__init__ of H is F.__init__; and
  • super().__init__ of F is object.__init__.

Note thus that super() does not per se delegates to a parent. For instance the super() of D is B and B is not a superclass of D, so it really depends on the type of the object (not on the class).

Now in case of D, the __mro__ is:

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

If we construct a D however we get:

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>

So in the context of D it holds that:

  • super().__init__ of D is E.__init__;
  • super().__init__ of E is G.__init__;
  • super().__init__ of G is H.__init__;
  • super().__init__ of H is F.__init__; and
  • super().__init__ of F is object.__init__.

So here the super() of D leads to E (for __init__) which is not the same in the context of A.

这篇关于super() 和 Parent 类名有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆