Mixin class data

Paul Moore paul.moore at atosorigin.com
Thu Oct 10 06:35:00 EDT 2002


[Following up on my own post]
> I have a suspicion that this needs the new-style class "cooperative
> super call" machinery. But I'm not 100% certain, [...]

OK, I've thought about this some more, and re-read the section of
descrintro on super(). I am not sure this works, but let's try it.

Assume that I have a base class B, and mixins M1, M2, ... The user is
expected to derive a class from B, and from as many or few of the Ms
as he likes. B must appear before the Ms in the base list. If the user
class has an __init__, it must call B.__init__(self), but it does not
need to know or care about whether the mixins have __init__ methods
(that's an implementation detail, subject to change).

I believe that these are reasonable restrictions, and I can live with
them. Given that, I think I can define B and the Ms as follows -

class B(object):
    def __init__(self):
        # do B's initialisation
        # Carry on down the chain of mixin initialisers
        super(B, self).__init__()

class M1(object):
    # The derivation from object is irrelevant here, but
    # keep it for consistency
    # No __init__ needed for this class

class M2(object):
    # This seems to need to derive from object, or B's super()
    # call doesn't find it...
    def __init__(self):
        # Do this class's initialisation
        # Is this super call needed? I think so...
        super(M2, self).__init__()

I believe this will work. The user class becomes a new-style class,
which may have some implications, but they shouldn't be a problem in
practice.

My questions are:

1. Why do the mixins need to derive from object? The ultimate user
class will be new-style, via B, so I don't see that the Ms need to
explicitly specify it. But the examples in descrintro don't use mixins
(they form a diamond pattern), so it's not entirely clear. Testing
indicates that mixins which use super() do need to derive from object.
It's just not clear to me why...

2. Is it OK for the user class to use the conventional
B.__init__(self) form? I'd prefer this to be true, as I don't want to
require the user of my class to understand (or even be aware of)
new-style classes and co-operative super calls to use it. I can't see
why it wouldn't be (after all, B's constructor still gets the full
object details via self), but again, descrintro isn't explicit on
this. Testing seems to indicate that this is OK.

As I mention, I've tested simple cases of this, but I'm concerned
about "dark corners". This stuff is useful, and powerful, but I don't
find it intuitive yet...

Thanks for any help in understanding this better,
Paul.



More information about the Python-list mailing list