跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 初学python,遇到一个问题搞不明白,求大佬解惑
未分類
8 4 月 2020

初学python,遇到一个问题搞不明白,求大佬解惑

nisekoi 大佬有话说 :

初学python,遇到一个问题搞不明白,求大佬解惑

本帖最后由 nisekoi 于 2020-4-4 21:30 编辑

代码是这样的 https://i.loli.net/2020/04/04/pIs5qelHtPfdxgT.png
这样的情况可以正常输出,注释不知道写没写对,如果错了希望大佬能指出一下,只写了四步是因为后面的理解不了执行顺序了。
后面如果B和C各调用一次A的init的话,应该会输出两次enter A leave A啊,为什么只输出了一次

但是如果把B类的super().__init__() 给注释掉,C就完全不会执行了。这是什么原理。非常困惑。求解。研究了一个多小时了
https://i.loli.net/2020/04/04/lYVIfPmX9S1p48h.png

我是一个大水怪 大佬有话说 :

本帖最后由 我是一个大水怪 于 2020-4-4 23:36 编辑

一般都是用Python写写简单的代码,很少涉及OOP的复杂部分。Python的OOP基本可以看作黑盒,无论是JS的令人诟病的原型链、还是Java,C++的经典继承模型,都有足够的资料供所学者参考,我所接触的Python学习资料没有详细的介绍它的OOP模型,基本都是点到为止,基础就够用了:单继承链的简单OOP模型。

多重继承就是OOP中的复杂部分。

就`super().__init____()`来说,基于深度优先搜索的`mro`顺序能解释继承的方法、属性的查找顺序,但无法解释`__init__()`方法的执行机制。

一个可以解释楼主示例的说法是根据`super()`的文档:
“`
Return a proxy object that delegates method calls to a parent or sibling class of type.
“`
根据D类的`mro`顺序:

D类的super()将__init__()委托给了B类
B类的super()将__init__()委托给了C类
C类的super()将__init__()委托给了A类

(以上委托只在D类的__init__()执行环境下有效。)

因此:

– A类的__init__()只会执行一次
– 当注释掉B类中的super()后,C类的__init__()就没有被调用,执行到B类为止

解释确实可以这样进行,但缺乏任何权威的资料来佐证我的以上解释,因此我始终把Python的OOP看作黑盒,也不会花精力去研究,因为对我而言没有意义。

如果真想研究,可以去看看Python的源码,毕竟开源。

Ftsb 大佬有话说 :

很简单的问题,书没仔细看
https://www.runoob.com/w3cnote/python-extends-init.html

朕的大清完了? 大佬有话说 :

人生苦短,你用python

mjsz 大佬有话说 :

super就是保证父类只执行一次。。。。

518 大佬有话说 :

因为如果D的两个父类方法名相同,就只继承第一个类的

likebeta 大佬有话说 :

python 2.7经典类 – 深度优先搜索基类继承函数,2.7的新式类(继承至object)和3.x – 广度优先搜索基类继承函数,基于这个原则如果和你想要的不符合,可以手动调用, 或者使用组合, 或者再往上抽象成非__init__方法再调用

518 大佬有话说 :

import sys

class A():
    def __init__(self):
      print("enter A")
      print("leave A")
      # print(self.__init__)
    def test(self):
      print("test A")

class B(A):
    def __init__(self):
      print("enter B")
      super().__init__()
      # super().test()
      print("leave B")
      print(super().__init__)

class C(A):
    def __init__(self):
      print("enter C")
      super().__init__()
      # super().test()
      print("leave C")
      print(super().__init__)

class D(B,C):
    def __init__(self):
      print("enter D")
      super().__init__()
      print("leave D")
      print(super().__init__)

if __name__ == ‘__main__’:
    d = D()
打印的是
enter D
enter B
enter C
enter A
leave A
<bound method D.__init__ of <__main__.D object at 0x117A9410>>
leave C
<bound method A.__init__ of <__main__.D object at 0x117A9410>>
leave B
<bound method C.__init__ of <__main__.D object at 0x117A9410>>
leave D
<bound method B.__init__ of <__main__.D object at 0x117A9410>>
你体会一下把

nisekoi 大佬有话说 :

518 大佬有话说 : 2020-4-4 22:10
打印的是
enter D
enter B

在去了解了一下继承和super的工作原理后终于搞明白了。

我是一个大水怪 大佬有话说 :

已经更新,欢迎探讨。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具