So I'm writing some code and have recently come across the need to implement a few mixins. My question is, what is the proper way to design a mix-in? I'll use the example code below to illustrate my exact query.
class Projectile(Movable, Rotatable, Bounded):
'''A projectile.'''
def __init__(self, bounds, position=(0, 0), heading=0.0):
Movable.__init__(self)
Rotatable.__init__(self, heading)
Bounded.__init__(self, bounds)
self.position = Vector(position)
def update(self, dt=1.0):
'''Update the state of the object.'''
scalar = self.velocity
heading = math.radians(self.heading)
direction = Vector([math.sin(heading), math.cos(heading)])
self.position += scalar * dt * direction
Bounded.update(self)
class Bounded(object):
'''A mix-in for bounded objects.'''
def __init__(self, bounds):
self.bounds = bounds
def update(self):
if not self.bounds.contains(self.rect):
while self.rect.top > self.bounds.top:
self.rect.centery += 1
while self.rect.bottom < self.bounds.bottom:
self.rect.centery += 1
while self.rect.left < self.bounds.left:
self.rect.centerx += 1
while self.rect.right > self.bounds.right:
self.rect.centerx -= 1
Basically, I'm wondering, are mix-ins sort of like Java interfaces where there is a sort of (in Python's case implicit) contract that if one wishes to use the code one must define certain variables / functions (not unlike a framework), or is it more like the code I've written above, where each mix-in must be initialized explicitly?
In Python, so-called mixins are classes that live in the normal inheritance tree, but they are kept small to avoid creating hierarchies that are too complicated for the programmer to grasp. In particular, mixins shouldn't have common ancestors other than object with the other parent classes.
A mixin is a class that provides methods to other classes, but it's not considered a base class itself. 00:18 This special class is going to expose some methods that the derived class can utilize—methods that will essentially be mixed in to the derived class.
Mixins are sometimes described as being "included" rather than "inherited". In short, the key difference from an inheritance is that mix-ins does NOT need to have a "is-a" relationship like in inheritance. From the implementation point of view, you can think it as an interface with implementations.
So to answer you're question, yes you may use parent attributes, if you make sure the parent has these attributes.
You can have both behavior in Python. You can force the reimplementation by using Abstract Base Classes, or by raising NotImplementedError in virtual functions.
If init are important in parent's classes, then you have to call them. As eryksun said, use the super
builtin function to call the parent's initializers (this way, an initializer for a given class will only be called once).
Conclusion: depends on what you have. In your case, you have to call init, and you should use super
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With