invoking a method from two superclasses

Carl Banks pavlovevidence at gmail.com
Wed Jul 1 23:18:22 EDT 2009


On Jun 30, 9:57 pm, Mitchell L Model <MLMLi... at Comcast.net> wrote:
> [Continuing the discussion about super() and __init__]
>
> The documentation of super points out that good design of
> diamond patterns require the methods to have the same
> signature throughout the diamond. That's fine for non-mixin
> classes where the diamond captures different ways of handling
> the same data.

[snip]

> The problem is that each mixin's __init__ is likely to have a
> different signature.

[snip]


Here are my recommendations for mixin classes.

1. Try to write mixins so that they don't need initializer arguments.
There's several approaches to this.  I prefer to burden the subclass
to set any attributes the mixin needs before calling super().__init__
().

class A(SomeMixin,SomeBaseClass):
    def __init__(self,arg1,arg2):
        self.some_attribute_needed_by_mixin = 10
        super().__init__(arg1,arg2)

That might seem a little weird to some (possibly because it is
impossible in C++ or Java to do that), but I find it to be a far more
versatile way for a subclass to send data to its parent.  I use it for
regular single inheritance, even.

Another possibility is to have a separate mixin initializer that is
called separately.

2. The __init__ of a mixin, if it has one, should always take *args
and **kwargs arguments, and only those arguments, and pass them as-is
to the superclass.

class SomeMixin:
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.use_somehow(self.some_attribute_needed_by_mixin)

If your mixin must have its own initializer argument, make it a
keyword-only argument, and have __init__ pop it off kwargs.

3. List mixin bases first among base classes.


I don't think Python provides an ideal way to do MI, BTW.  I believe
that's by design: MI is somewhat troublesome specifically to
discourage overuse.  As a power MI user, I am fine with this.


> I think I'd be back to having to call each mixin class's
> __init__ explicitly:

I'd say never mix super() and direct calls, for any reason.  Pick one
and go with it.


Carl Banks



More information about the Python-list mailing list