I'm reading Alex Martelli's "Nutshell" second edition. In the section called "Cooperative superclass method calling", he presents a diamond inheritance hierachy:
class A(object): def met(self): print "A.met" class B(A): def met(self): print "B.met" A.met(self) class C(A): def met(self): print "C.met" A.met(self) class D(B,C): def met(self): print "D.met" B.met(self) C.met(self) D().met() # essentially "D B A C A" Martelli says "In this code, when we call D().met(), A.met ends up being called twice. How can we ensure that each ancestor's implementation of the method is called once, and only once? The solution is to use built-in type super. super(aclass, obj), which returns a special superobject of object obj. When we look up an attribute (e.g., a method) in this superobject, the lookup begins after class aclass in obj's MRO. We can therefore rewrite the previous code as: class A(object): def met(self): print "A.met" class B(A): def met(self): print "B.met" super(B, self).met() class C(A): def met(self): print "C.met" super(C, self).met() class D(B,C): def met(self): print "D.met" super(D, self).met() D().met() # essentially "D B C A" Now, D().met() results in exactly one call to each class's version of met." I see that this is true, but I am confused by the explanation (the bit about truncated lookup in the class's MRO). In particular: 1. The super() call in D somehow invokes both parent class methods instead of stopping when the method is resolved in B. This has nothing to do with truncated lookup per se. Why isn't the output "D B A"? 2. If I understand correctly, B's MRO is (B, A) and super(B, self) would have an MRO of (A). Similarly for C. So it seems that by the above explanation, A.met() would still be invoked twice (assuming both B.met() and C.met() are invoked). I guess I can just take it on faith that super() invokes everything once and only once, but I'd rather understand how. Can someone point me to a more complete description of super()'s semantics and how they work? BTW, the official docs are even worse in this regard. AFAICT, they essentially say that super() returns a superclass with no discussion of diamond inheritance or any hint of how the semantics of super(B, self).met() would be any different than those of A.met(self). This seems like very important functionality to be documented in the official docs so poorly. Mike -- http://mail.python.org/mailman/listinfo/python-list