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)
?
在 这种情况下 不是。但是 通常 ,尤其是当您使用 多重继承时
,按照文档中指定 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__
的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()
它 本身 并不 委托给父母
。例如,super()
ofD
是B
andB
不是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__
的D
是E.__init__
;super().__init__
的E
是G.__init__
;super().__init__
的G
是H.__init__
;super().__init__
的H
是F.__init__
; 和super().__init__
的F
是object.__init__
。因此,这里 的super()
的D
导致E
(对于__init__
)这是 不是在上下文中的相同A
。
谢谢你抽出时间。 问候,
问题内容: 在Java中,这些之间有什么区别: 我已经多次检查过Javadoc,但这从来不能很好地解释它。我也进行了测试,但没有反映出调用这些方法背后的任何实际含义。 问题答案: 如果不确定某件事,请尝试先编写测试。 我这样做: 印刷品: 最后一个块中有一个空条目,其中返回一个空字符串。 结果是: 该 名称 是您愿意使用动态加载与类,例如,调用的名称与默认。在一定范围内,所有类都有唯一的名称。 该
问题内容: 在此示例中: 无法编译为: 而被编译器接受。 这个答案说明唯一的区别是,与不同,它允许您稍后引用类型,似乎并非如此。 是什么区别,并在这种情况下,为什么不第一编译? 问题答案: 通过使用以下签名定义方法: 并像这样调用它: 在jls§8.1.2中,我们发现(有趣的部分被我加粗了): 通用类声明定义了一组参数化类型(第4.5节), 每种可能通过类型arguments调用类型参数节的类型
我正在测试上面的代码。两者给我的结果是一样的。我正试图理解第1、2和6行之间的区别。我可以通过这两种方法获得相同的结果。
问题内容: 当是重要的传球到了,为什么? 问题答案: 只有一种原因需要传递给: 当您要在构造函数中访问时。 通过: 未通过: 注意,通过或不通过,以有 没有影响 对以后的用途之外。也就是说,或事件处理程序 始终 可以访问它。 这是索菲·阿尔珀特(Sophie Alpert)对类似问题的回答中明确指出的。 建议使用“ 状态和生命周期,将本地状态添加到类,第2点”中的文档: 类组件应始终使用调用基本构
问题内容: 我不清楚两者之间的区别。 谢谢 问题答案: 它们非常相似,但是存在一些重要的技术差异: 抽象类允许您为某些方法提供默认的实现,但是接口不允许您提供任何实现。 您可以实现多个接口,但只能从一个抽象类继承。 这些差异影响应使用两种技术的方式: 您应该使用接口来 定义合同 。 抽象类对于 重用代码 很有 用 ……但是请注意,它不是重用代码的唯一方法。您还应该考虑其他方法,例如遏制。