How to improve a mixin structure in Python?
<p>I have a simple mixin structure in Python. The code should be pretty self-explaining:</p>

<pre><code>class Base:
    def __init__(self):
        pass

class MixinA:
    def __init__(self):
        self.x = 0
        self.y = 1
    def a(self):
        print('A: x = ' + str(self.x) + ', y = ' + str(self.y))

class MixinB:
    def __init__(self):
        self.x = 2
        self.z = 3
    def b(self):
        print('B: x = ' + str(self.x) + ', z = ' + str(self.z))

class MyFirstMix(MixinA, MixinB, Base):
    def __init__(self):
        Base.__init__(self)
        MixinB.__init__(self)
        MixinA.__init__(self)

class MySecondMix(MixinA, Base):
    def __init__(self):
        Base.__init__(self)
        MixinA.__init__(self)
</code></pre>

<p>I'd like to improve this a bit, so this leads to 3 questions/problems:</p>

<ol>
<li><code>MixinA</code> and <code>MixinB</code> both have a member <code>x</code>. Is there a way to make sure, each of the class sees only its own x<code>?</code> As far as I know: No, there isn't.</li>
<li>It's slightly cumbersome to call the constructor for each mixin in the mixed class. Is there a way to automatically call all constructors or to do something with the same effect?</li>
<li>Is there a way to dynamically mixin something in-line, without explicitly creating a class? I'm looking for a syntax like: <code>mix = Base() with MixinA</code></li>
</ol>

<p>If my proposed structure is completely wrong, I'm also open for other recommendations on how to handle mixins.</p>

<p>For python class inherent, I believe there are some tricks you need to know:</p>

<ol>
<li><p>Class in python2 and python3 are quite different.
Python2 support old-style class, but python3 support new-style class only. Simply speaking: in python3, classes always inherent from a base class <code>object</code>, even though you do not explicitly use it. Check <a href="http://stackoverflow.com/questions/54867/what-is-the-difference-between-old-style-and-new-style-classes-in-python">Difference-between-Old-New-Class</a>.</p></li>
<li><p>Method Resolution Order (MRO). This determines how derived class search inherent members and functions. See <a href="http://python-history.blogspot.com/2010/06/method-resolution-order.html" rel="nofollow">MRO</a></p></li>
<li><p><code>super</code> function. Combined with MRO, you can easily call parent member or function, without explicitly know the name of parent class. See <a href="http://stackoverflow.com/questions/607186/how-does-pythons-super-do-the-right-thing">Super</a></p></li>
</ol>

<p>Now comes to you questions:</p>

<ol>
<li>MixinA and MixinB both have a member x. Is there a way to make sure, each of the class sees only its own x?</li>
</ol>

<p>I don't quit understand your meaning. When you refer a class member, you must refer it through its instance or class. So <code>instance_of_MixinA.x</code> and <code>instance_of_MixinB.x</code> are separated. If you are talking about class <code>MyFirstMix(MixinA, MixinB, Base)</code>, it depends on how <code>__init__</code> function is called. In your code, you first populate <code>x</code> by <code>MixinB</code> and then reset its value by <code>MixinA</code>. </p>

<ol start="2">
<li>It's slightly cumbersome to call the constructor for each mixin in the mixed class. Is there a way to automatically call all constructors or to do something with the same effect.</li>
</ol>

<p>Your designation make it impossible. You have to call all constructors.</p>

<ol start="3">
<li>Is there a way to dynamically mixin something in-line, without explicitly creating a class?</li>
</ol>

<p>I am not sure. But I can give you some suggestions: try outside <code>__init__</code> members when def class (python3, if you used python2 take care of <code>super</code>):</p>

<pre><code>class Base:
    def __init__(self):
        pass


class MixinA:
    x = 0
    y = 1


class MixinB:
    x = 2
    z = 3

    def b(self):
        print('B: x = ' + str(self.x) + ', z = ' + str(self.z))


class MyFirstMix(MixinA, MixinB, Base):
    def __init__(self):
        super().__init__()


class MySecondMix(MixinA, Base):
    def __init__(self):
        super().__init__()
</code></pre>

<p>The variables outside <code>__init__</code> behaves quit different from inside variables: outside variables belongs to class and will be populated for all instances of this class, while inside variables belongs only to instance (referred by <code>self</code> when you define class), and will be populated only if <code>__init__</code> is called. That's why you cannot use <code>super</code> to call all the constructors---<code>super</code> only call the priority parent's <code>__init__</code>. See <a href="http://stackoverflow.com/questions/1537202/variables-inside-and-outside-of-a-class-init-function">variables-outsite-inside-init</a></p>

<p>This is a good solution to Mixin class. In above code, <code>MyFirstMix</code> inherents both <code>MixinA</code> and <code>MixinB</code> whose members are all class members (outside <code>__init__</code>). So instances of <code>MyFirstMix</code> will inherent all class members of <code>MixinA</code> and <code>MixinB</code> without call <code>__init__</code>. Here <code>MixinA</code> and <code>MixinB</code> own same class member <code>x</code>, but the <code>MRO</code> determines that when instances of <code>MyFirstMix</code> refer <code>x</code>, <code>x</code> from <code>MixinA</code> should be returned.</p>

<p>Hope this will be helpful. Thanks!</p>

python mixins