How to call super of enclosing class in a mixin in Python?
<p>I have the following code, in Django:</p>

<pre><code>class Parent(models.Model):
    def save(self):
        # Do Stuff A

class Mixin(object):
    def save(self):
        # Do Stuff B

class A(Parent, Mixin):
    def save(self):
        super(A, self).save()
        # Do stuff C
</code></pre>

<p>Now, I want to use the mixin without blatting the behaviour of the save in Parent. So I when I save, I want to do stuff C, B, and A. I've read <a href="http://stackoverflow.com/questions/27664632/calling-the-setter-of-a-super-class-in-a-mixin">Calling the setter of a super class in a mixin</a> however I don't get it and having read the super docs it doesn't seem to answer my question.</p>

<p>THe question is, what do I put in the mixin to make sure it does stuff B and doesn't stop Stuff A from happening?</p>

<p>The bast practice for calling the implementation from the superclass is to use <code>super</code>:</p>

<pre><code>class Mixin(object):
    def save(self):
        super(Mixin, self).save()
        # Do Stuff B here or before super call, as you wish
</code></pre>

<p>What is important is that you call <code>super</code> in each class (so that it propagates all the way) but not the topmost (base) class, because its superclass does not have <code>save</code>.</p>

<p>Note that when you call <code>super(Mixin, self).save()</code>, you don't really know what the super class would be once it is executed. That will be defined later.</p>

<p>Unlike some other languages, in python, the end class will always have a linear list of classes from which it inherits. That is called MRO (<a href="https://www.python.org/download/releases/2.3/mro/" rel="nofollow">Method Resolution Order</a>). From MRO Python decides what to do on <code>super</code> call. You can see what the MRO iss for your class this way:</p>

<pre><code>&gt;&gt;&gt; A.__mro__
(&lt;class '__main__.A'&gt;, &lt;class '__main__.Parent'&gt;, &lt;class '__main__.Model'&gt;, &lt;class '__main__.Mixin'&gt;, &lt;type 'object'&gt;)
</code></pre>

<p>So, A's super is Parent, Parent's super is Model, Model's super is Mixin and Mixin's super is object.</p>

<p>That is wrong, so you should change A's parents to:</p>

<pre><code>class A(Mixin, Parent):
</code></pre>

<p>Then you'd have a better MRO:</p>

<pre><code>&gt;&gt;&gt; A.__mro__
(&lt;class '__main__.A'&gt;, &lt;class '__main__.Mixin'&gt;, &lt;class '__main__.Parent'&gt;, &lt;class '__main__.Model'&gt;, &lt;type 'object'&gt;)
</code></pre>

python