Multiple inheritance - How to call method_x in InheritedBaseB from method_x in InheritedBaseA?

The Music Guy musicguy at alphaios.net
Wed Sep 9 19:37:35 EDT 2009


On Wed, Sep 9, 2009 at 1:21 PM, Carl Banks<pavlovevidence at gmail.com> wrote:
> On Sep 8, 10:47 pm, The Music Guy <music... at alphaios.net> wrote:

> What is get_other_base?  Just use a regular super call here,
> get_other_base and hacks like that are what gets you into trouble.
>
> You seem to be overthinking this.  You don't need to.  Just use super
> () in MyMixin, and in all the other classes, consistently, and mind
> the order of the bases.
>
> And if I were you I wouldn't keep making updates to a "current
> example" because first you do questionable things define a
> get_other_base method, then you try to apply my advice without
> reverting to the original form you posted.  Well of course you're
> going to have issues if you do that.  Instead, start from scratch, and
> try to get a small example working, using your orginial post and my
> original suggestion.  Once that works then try to apply it to your
> working example.
>

get_other_base() is supposed to return the other superclass (base)
that is being used in conjunction with the current superclass. So if
FooX inherits from MyMixin and BaseB, and get_other_base(self) is
called from a method defined in MyMixin, BaseB is returned. In any
case, that function is merely psuedocode, not an actual part of the
implementation. Its purpose in my example was merely to show the
effect I was trying to acheive. I used it because I'm having trouble
understanding exactly how the super() function works; it always seems
to do something I didn't expect, or not do something that I did
expect. (I say this after having read the online documentation, btw.)

Anyway, Ryles' last suggestion helped a lot. Thanks, Ryles. (And Carl
and Scott, too, of course.) Here's the code I'm going with:

def main():

    basea = BaseA()
    baseb = BaseB()
    basec = BaseC()

    foox = FooX()
    fooy = FooY()
    fooz = FooZ()

    basea.method_x("I", "Am", "BaseA!");
    print
    baseb.method_x("One", "Two", "Three");
    print
    basec.method_x("Ay", "Bee", "See");
    print

    print

    foox.method_x("I", "AM", "X")
    print
    fooy.method_x("ESTOY", "Y", "!")
    print
    fooz.method_x(100, 200, 300)


class MyMixin(object):

    def method_x(self, a, b, c):
        super(MyMixin, self).method_x(a, b, c)
        print "MyMixin.method_x(%s, %s, %s, %s)" % (repr(self),
repr(a), repr(b), repr(c))

class CommonBase(object):

    def method_x(self, a, b, c):
        print "CommonBase.method_x(%s, %s, %s, %s)" % (repr(self),
repr(a), repr(b), repr(c))

class BaseA(CommonBase):

    def method_x(self, a, b, c):
        super(BaseA, self).method_x(a, b, c)
        print "BaseA.method_x(%s, %s, %s, %s)" % (repr(self), repr(a),
repr(b), repr(c))

class BaseB(CommonBase):

    def method_x(self, a, b, c):
        super(BaseB, self).method_x(a, b, c)
        print "BaseB.method_x(%s, %s, %s, %s)" % (repr(self), repr(a),
repr(b), repr(c))

class BaseC(CommonBase):

    pass

class FooX(MyMixin, BaseA):

    def method_x(self, a, b, c):
        super(FooX, self).method_x(a, b, c)
        print "FooX.method_x(%s, %s, %s, %s)" % (repr(self), repr(a),
repr(b), repr(c))

class FooY(MyMixin, BaseB):

    pass

class FooZ(MyMixin, BaseC):

    def method_x(self, a, b, c):
        super(FooZ, self).method_x(a, b, c)
        print "FooZ.method_x(%s, %s, %s, %s)" % (repr(self), repr(a),
repr(b), repr(c))

if __name__ == '__main__':
    main()


Output:


CommonBase.method_x(<__main__.BaseA object at 0xb7d0d42c>, 'I', 'Am', 'BaseA!')
BaseA.method_x(<__main__.BaseA object at 0xb7d0d42c>, 'I', 'Am', 'BaseA!')

CommonBase.method_x(<__main__.BaseB object at 0xb7d0d44c>, 'One',
'Two', 'Three')
BaseB.method_x(<__main__.BaseB object at 0xb7d0d44c>, 'One', 'Two', 'Three')

CommonBase.method_x(<__main__.BaseC object at 0xb7d0d46c>, 'Ay', 'Bee', 'See')


CommonBase.method_x(<__main__.FooX object at 0xb7d0d48c>, 'I', 'AM', 'X')
BaseA.method_x(<__main__.FooX object at 0xb7d0d48c>, 'I', 'AM', 'X')
MyMixin.method_x(<__main__.FooX object at 0xb7d0d48c>, 'I', 'AM', 'X')
FooX.method_x(<__main__.FooX object at 0xb7d0d48c>, 'I', 'AM', 'X')

CommonBase.method_x(<__main__.FooY object at 0xb7d0d4ac>, 'ESTOY', 'Y', '!')
BaseB.method_x(<__main__.FooY object at 0xb7d0d4ac>, 'ESTOY', 'Y', '!')
MyMixin.method_x(<__main__.FooY object at 0xb7d0d4ac>, 'ESTOY', 'Y', '!')

CommonBase.method_x(<__main__.FooZ object at 0xb7d0d4cc>, 100, 200, 300)
MyMixin.method_x(<__main__.FooZ object at 0xb7d0d4cc>, 100, 200, 300)
FooZ.method_x(<__main__.FooZ object at 0xb7d0d4cc>, 100, 200, 300)


You may notice that MyMixin calls the super's method before doing
anything of its own. This is intentional--MyMixin's job cannot be done
correctly until the other bases have done their part.



More information about the Python-list mailing list