Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

In Python, we use mixins. Mixins can only inherit from 'object' and nothing else, like this:

    class PhysicsobjectMixin(object):
        def update_physics(self):
            pass
        
        def apply_konckback(self, force):
            pass

        def get_position(self):
            pass


    class FightMixin(object):
        def attack(self):
            pass

        def defend(self):
            pass

    
    class TalkMixin(object):
        def say_something(self):
            pass


    class Character(PhysicsobjectMixin, FightMixin, TalkMixin):
        pass


    class Pickup(PhysicsobjectMixin):
        pass


    class Projectile(PhysicsobjectMixin):
        pass

it's still inheritance, but the classes will be flat; every class only inherits one deep, so there will be no diamond problems and no repeating code.


That's just normal multiple-inheritance. Nothing like mixins.

Mixins would be if the classes actually contribute pieces which combine in an interesting way. Like a border-mixin added to a button class would add to the drawing and to the geometry of the object.


Actually some cases of mixins are equivalent to multiple inheritance.


I don't know if you've ever used Django, but the entire thing is based on inheritance. When they introduced Class Based Views it got so complex that someone had to make this site just for exploring the inheritance tree: http://ccbv.co.uk


There is a good discussion about it here: http://lukeplant.me.uk/blog/posts/djangos-cbvs-were-a-mistak...


Is that just multiple inheritance, or are mixins something else?


Multiple inheritance with your discipline to not do more complicated things. Only inherit from base 'object', nothing else, so you will have no complicated inheritance problems.


Which, in reality, rarely happens. Looking through the code in the Python standard library shows how even the exemplar mixin examples are rarely so pure.


I don't see the difference to interfaces.


With interfaces, the above example would look like this:

    from abc import ABCMeta   

    class PhysicsobjectMixin(ABCMeta):
        @abstractmethod
        def update_physics(self):
            pass
        
        @abstractmethod
        def apply_konckback(self, force):
            pass

        @abstractmethod
        def get_position(self):
            pass


    class FightMixin(ABCMeta):
        @abstractmethod
        def attack(self):
            pass

        @abstractmethod
        def defend(self):
            pass

    
    class TalkMixin(ABCMeta):
        @abstractmethod
        def say_something(self):
            pass


    class Character(PhysicsobjectMixin, FightMixin, TalkMixin):
        def update_physics(self):
            pass

        def apply_konckback(self, force):
            pass

        def get_position(self):
            pass

        def attack(self):
            pass

        def defend(self):
            pass

        def say_something(self):
            pass


    class Pickup(PhysicsobjectMixin):
        def update_physics(self):
            pass
        
        def apply_konckback(self, force):
            pass

        def get_position(self):
            pass


    class Projectile(PhysicsobjectMixin):
        def update_physics(self):
            pass
        
        def apply_konckback(self, force):
            pass

        def get_position(self):
            pass

This is not DRY at all. I like mixins much better.


It's not DRY, but then again, the chances of not overwriting, or more likely adding something to that method are pretty small when your project becomes more than an illustration of a principle.

For example, what if you want to add custom animations any time your `Character` takes an action? Suddenly, all that boilerplate you "abstracted" away through mix-ins is back, with a vengeance. How about if your physics for a `Projectile` are different than for a `Pickup`? What if your character suddenly picks up a Sling of Thrown Voices, and needs to apply conversation snippets to its projectiles?

In simple examples, mixins are great and reduce a lot of boilerplate, but in reality they are rarely so clean.


> For example, what if you want to add custom animations any time your `Character` takes an action?

What's wrong with this?

    class Character(PhysicsobjectMixin, FightMixin, TalkMixin):
        def attack(self):
            # custom attack animation here
            return super(Character, self).attack()

        def defend(self):
            # custom defend animation here
            return super(Character, self).defend()
For me, it's still clear that 'attack' and 'defend' extends the funcionality of the 'FightMixin'. I can see even the first glance, those are inherited methods, because they use super() (call parent methods)

> How about if your physics for a `Projectile` are different than for a `Pickup`?

You need to implement two classes anyway. I see two possibilities:

I. If you have to implement this kind of different physics behavior only for Projectile. (Maybe you don't even need a mixin.)

    class Projectile(object):
        def update_physics(self):
            pass
        
        def apply_konckback(self, force):
            pass

        def get_position(self):
            pass

II. If you have more Projectile-like objects, but they are not all the same.

   class FastMovingPhysicsobjectMixin(object):
        def update_physics(self):
            pass
        
        def apply_konckback(self, force):
            pass

        def get_position(self):
            pass


    class Projectile(FastMovingPhysicsobjectMixin):
        pass

    
    class Arrow(FastMovingPhysicsobjectMixin):
        pass

> What if your character suddenly picks up a Sling of Thrown Voices, and needs to apply conversation snippets to its projectiles?

Is this a weapon which doesn't shoot projectiles, but make damage with voice or what? :D Then I think it's totally different, because if Character can have all kinds of different weapons and those behave different ways, mixins don't fit here. I would rather implement that like this:

    class Sword(object):
        def attack(self):
            # swing

        def defend(self):
            # defend

    
    class SlingOfThrownVoices(object):
        def attack(self):
            # shout loudly

        def defend(self):
            # pssszt, be quiet
    

    class Character(PhysicsobjectMixin, TalkMixin):
        def __init__(self, weapon):
            self.weapon = weapon

        def attack(self):
            # custom attack animation here
            self.weapon.attack()

        def defend(self):
            # custom defend animation here
            self.weapon.defend()
then weapon can be instance of either Sword or SlingOfThrownVoices. Note that Mixins are still in use and no complicated inheritance problem occured even if you have hundreds of weapons.


The stuff you mix in has code. Interfaces do not.


What code do you mean? He only wrote "pass". I guess I'm confused because he still used inheritance.


There was a place to write code. In this example, obviously, none was written. But interfaces leave no opportunity.


The difference is that those aren't interfaces. I'm confused by the question?




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: