当前位置: 首页 > 面试题库 >

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

丁慈
2023-03-14
问题内容

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



 类似资料:
  • 问题内容: 在Java中,这些之间有什么区别: 我已经多次检查过Javadoc,但这从来不能很好地解释它。我也进行了测试,但没有反映出调用这些方法背后的任何实际含义。 问题答案: 如果不确定某件事,请尝试先编写测试。 我这样做: 印刷品: 最后一个块中有一个空条目,其中返回一个空字符串。 结果是: 该 名称 是您愿意使用动态加载与类,例如,调用的名称与默认。在一定范围内,所有类都有唯一的名称。 该

  • 问题内容: 在此示例中: 无法编译为: 而被编译器接受。 这个答案说明唯一的区别是,与不同,它允许您稍后引用类型,似乎并非如此。 是什么区别,并在这种情况下,为什么不第一编译? 问题答案: 通过使用以下签名定义方法: 并像这样调用它: 在jls§8.1.2中,我们发现(有趣的部分被我加粗了): 通用类声明定义了一组参数化类型(第4.5节), 每种可能通过类型arguments调用类型参数节的类型

  • 我正在测试上面的代码。两者给我的结果是一样的。我正试图理解第1、2和6行之间的区别。我可以通过这两种方法获得相同的结果。

  • 问题内容: 当是重要的传球到了,为什么? 问题答案: 只有一种原因需要传递给: 当您要在构造函数中访问时。 通过: 未通过: 注意,通过或不通过,以有 没有影响 对以后的用途之外。也就是说,或事件处理程序 始终 可以访问它。 这是索菲·阿尔珀特(Sophie Alpert)对类似问题的回答中明确指出的。 建议使用“ 状态和生命周期,将本地状态添加到类,第2点”中的文档: 类组件应始终使用调用基本构

  • 问题内容: 我不清楚两者之间的区别。 谢谢 问题答案: 它们非常相似,但是存在一些重要的技术差异: 抽象类允许您为某些方法提供默认的实现,但是接口不允许您提供任何实现。 您可以实现多个接口,但只能从一个抽象类继承。 这些差异影响应使用两种技术的方式: 您应该使用接口来 定义合同 。 抽象类对于 重用代码 很有 用 ……但是请注意,它不是重用代码的唯一方法。您还应该考虑其他方法,例如遏制。