Composition instead of inheritance

Ian Kelly ian.g.kelly at gmail.com
Fri Apr 29 20:39:03 EDT 2011


On Fri, Apr 29, 2011 at 5:54 PM, Carl Banks <pavlovevidence at gmail.com> wrote:
>> Really, *any* class that uses super().__init__ should take its
>> arguments and pass them along in this manner.
>
> If you are programming defensively for any possible scenario, you might try this (and you'd still fail).
>
> In the real world, certain classes might have more or less probability to be used in a multiple inheritance situations, and programmer needs to weigh the probability of that versus the loss of readability.  For me, except when I'm designing a class specifically to participate in MI (such as a mixin), readability wins.

Agreed.  Actually, my preferred solution is to not use super at all.
It's so rarely needed (i.e. diamond inheritance situations) that it's
usually not worth it to jump through the hoops it creates, so I prefer
to call the base class methods explicitly.

For pure base-class + mixin design, you should not have any diamond
inheritance situations, so super should not really be necessary.

> If you merely mean DRY, then I'd say this doesn't necessarily add to it.  The derived class has a responsibility one way or another to get the mixin whatever initializers it needs.

I mean the difference in terms of maintenance between this:

class Derived1(Mixin1, Base):
    def __init__(self, mixin_arg1, mixin_arg2, *args, **kwargs):
        self.mixin_arg1 = mixin_arg1
        self.mixin_arg2 = mixin_arg2
        super(Derived, self).__init__(*args, **kwargs)

and simply doing this:

class Derived2(Mixin2, Base):
    def __init__(self, *args, **kwargs):
        super(Derived, self).__init__(*args, **kwargs)

In both cases we are passing the arguments in to the mixin.  In the
former case, if we later decide to add mixin_arg3, then we have to
also add it to the Derived1.__init__ signature and then add a line to
set the attribute.  In the latter case, adding mixin_arg3 has no
effect on the Derived2 initializer at all, because it passes through
transparently in the kwargs.

Cheers,
Ian



More information about the Python-list mailing list