python multiple inheritance qustion

醉酒当歌 提交于 2020-03-27 08:26:33

问题


This is an interview example question I copied and modified from question 10 of: https://www.codementor.io/sheena/essential-python-interview-questions-du107ozr6

class A(object):
    def go(self):
        print("go A go!")
    def stop(self):
        print("stop A stop!")

class B(A):
    def go(self):
        super(B, self).go()
        print("go B go!")

class C(A):
    def go(self):
        super(C, self).go()
        print("go C go!")
    def stop(self):
        super(C, self).stop()
        print("stop C stop!")

class D(B,C):
    def go(self):
        super(D, self).go()
        print("go D go!")
    def stop(self):
        super(D, self).stop()
        print("stop D stop!")

class E(B,C): pass
a = A()
b = B()
c = C()
d = D()
e = E()
print "call b.stop()......."
b.stop()
print "call d.stop()......."
d.stop()
print "call e.stop()......."
e.stop()

answer is:

call b.stop().......
stop A stop!
call d.stop().......
stop A stop!
stop C stop!    
stop D stop!  #?why not having b.stop() which leads to "stop A stop!"
call e.stop().......
stop A stop!
stop C stop!

I understand calling b.stop() shows "stop A stop!" because b does not override stop() so will inherit stop() from A.

But I do not understand why calling d.stop() only show stop of A,C,D, not ACBD, isn't MRO: D->B->C->A?

and I do not understand why calling e.stop() only shows stop of A and C, based on MRO: E->B->C->A, I think e.stop() should inherit from B's stop(), so should be stop A stop, stop C stop, then stop B stop?

I must have misunderstand sth. about super I guess.


回答1:


I understand calling b.stop() shows "stop A stop!" because b does not override stop() so will inherit stop() from A.

But I do not understand why calling d.stop() only show stop of A,C,D, not ACBD, isn't MRO: D->B->C->A?

B inherits stop from A, but what that means is that when you try to access B.stop or some_B_instance.stop, the attribute search will find the method through A.__dict__ after looking in B.__dict__. It doesn't put the method in the B class directly.

When super follows the MRO of a D instance, class B comes after D, but super is only interested in looking at B itself at this point, not B's ancestors. It looks in B.__dict__ for a stop entry, without considering inherited methods; inherited methods will be handled later in the search, when super reaches the classes those methods are inherited from.

Since inheriting methods doesn't actually put them in B.__dict__, super doesn't find stop in B.




回答2:


B does not have its own stop (you'll notice the string "stop B stop" never appears in the code), so it will never be executed. In other worse, since there is no line of code which could possibly print "stop B stop", it will not be printed.



来源:https://stackoverflow.com/questions/46335165/python-multiple-inheritance-qustion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!