0

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.

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

ok, so "super is only interested in looking at B itself not ancestor", . got it. Thanks.
1

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.

3 Comments

but calling b.stop() shows "stop A stop!", which means b.stop() is available?
Yes but it shows up as stop A stop! even though it is b.stop
B does not have its own stop. It inherits stop from A.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.