super() 和 Parent 类名有什么区别? [英] What's the difference between super() and Parent class name?
问题描述
使用 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__
的A
是D.__init__
;super().__init__
的D
是B.__init__
;super().__init__
的B
是C.__init__
;super().__init__
的C
是E.__init__
;super().__init__
的E
是G.__init__
;super().__init__
的G
是H.__init__
;super().__init__
的H
是F.__init__
;和super().__init__
的F
是object.__init__
.
因此请注意,super()
本身不会委托给父级.例如 D
的 super()
是 B
而 B
不是 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__
的D
是E.__init__
;super().__init__
的E
是G.__init__
;super().__init__
的G
是H.__init__
;super().__init__
的H
是F.__init__
;和super().__init__
的F
是object.__init__
.
所以这里D
的super()
导致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 bothgetattr()
andsuper()
. 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__
ofA
isD.__init__
;super().__init__
ofD
isB.__init__
;super().__init__
ofB
isC.__init__
;super().__init__
ofC
isE.__init__
;super().__init__
ofE
isG.__init__
;super().__init__
ofG
isH.__init__
;super().__init__
ofH
isF.__init__
; andsuper().__init__
ofF
isobject.__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__
ofD
isE.__init__
;super().__init__
ofE
isG.__init__
;super().__init__
ofG
isH.__init__
;super().__init__
ofH
isF.__init__
; andsuper().__init__
ofF
isobject.__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屋!