For python class inherent, I believe there are some tricks you need to know:
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 object
, even though you do not explicitly use it. Check Difference-between-Old-New-Class.
Method Resolution Order (MRO). This determines how derived class search inherent members and functions. See MRO
super
function. Combined with MRO, you can easily call parent member or function, without explicitly know the name of parent class. See Super
Now comes to you questions:
- MixinA and MixinB both have a member x. Is there a way to make sure, each of the class sees only its own x?
I don't quit understand your meaning. When you refer a class member, you must refer it through its instance or class. So instance_of_MixinA.x
and instance_of_MixinB.x
are separated. If you are talking about class MyFirstMix(MixinA, MixinB, Base)
, it depends on how __init__
function is called. In your code, you first populate x
by MixinB
and then reset its value by MixinA
.
- 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.
Your designation make it impossible. You have to call all constructors.
- Is there a way to dynamically mixin something in-line, without explicitly creating a class?
I am not sure. But I can give you some suggestions: try outside __init__
members when def class (python3, if you used python2 take care of super
):
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__()
The variables outside __init__
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 self
when you define class), and will be populated only if __init__
is called. That's why you cannot use super
to call all the constructors---super
only call the priority parent's __init__
. See variables-outsite-inside-init
This is a good solution to Mixin class. In above code, MyFirstMix
inherents both MixinA
and MixinB
whose members are all class members (outside __init__
). So instances of MyFirstMix
will inherent all class members of MixinA
and MixinB
without call __init__
. Here MixinA
and MixinB
own same class member x
, but the MRO
determines that when instances of MyFirstMix
refer x
, x
from MixinA
should be returned.
Hope this will be helpful. Thanks!