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的工作原理后终于搞明白了。
我是一个大水怪 大佬有话说 :
已经更新,欢迎探讨。