Your code has nothing to do with the method resolution order. Method resolution occurs in the case of multiple inheritance, which is not relevant to your example. Your code is simply incorrect because you think that self.__class__ is actually the same class of where the method is defined, and this is not true:
>>> class A(object): ... def __init__(self): ... print self.__class__ ... >>> >>> class B(A): ... def __init__(self): ... A.__init__(self) ... >>> B() <class '__main__.B'> <__main__.B object at 0x1bcfed0> >>> A() <class '__main__.A'> <__main__.A object at 0x1bcff90> >>>
so when you should call:
super(B, self).__init__(1, b, c)
you really call:
# super(self.__class__, self).__init__(1, b, c) super(C, self).__init__(1, b, c)
EDIT : to better answer the question.
class A(object): def __init__(self, a): for cls in self.__class__.mro(): if cls is not object: cls._init(self, a) def _init(self, a): print 'A._init' self.a = a class B(A): def _init(self, a): print 'B._init' class C(A): def _init(self, a): print 'C._init' class D(B, C): def _init(self, a): print 'D._init' d = D(3) print da
prints:
D._init B._init C._init A._init 3
(Modified version of the template ).
Now the parent methods are really called implicitly, but I have to agree with python zen where explicit is better than implicit because the code is less readable and the payoff is bad. But be careful that all _init methods have the same parameters, you cannot completely forget about the parents, and I do not suggest doing this.
For single inheritance, the best approach explicitly calls the parent method without calling super . You do not need to name the current class for this, but you should still care about who the parent class is.
Well reads: how-does-pythons-super-do-the-right-thing and the links suggested in this question and especially Python Super are great, but you can't use it
If the hierarchy is likely to change, these are symptoms of poor design and consequences for all parts that use this code and should not be encouraged.
EDIT 2
Another example concerns me, but uses metaclasses. The urwid library uses a metaclass to store the __super attribute in the class, so you just need to access this attribute.
Example:
>>> class MetaSuper(type): ... """adding .__super""" ... def __init__(cls, name, bases, d): ... super(MetaSuper, cls).__init__(name, bases, d) ... if hasattr(cls, "_%s__super" % name): ... raise AttributeError, "Class has same name as one of its super classes" ... setattr(cls, "_%s__super" % name, super(cls)) ... >>> class A: ... __metaclass__ = MetaSuper ... def __init__(self, a): ... self.a = a ... print 'A.__init__' ... >>> class B(A): ... def __init__(self, a): ... print 'B.__init__' ... self.__super.__init__(a) ... >>> b = B(42) B.__init__ A.__init__ >>> ba 42 >>>