On Sep 4, 6:01 am, The Music Guy <music...@alphaios.net> wrote: > I have a peculiar problem that involves multiple inheritance and method > calling. > > I have a bunch of classes, one of which is called MyMixin and doesn't > inherit from anything. MyMixin expects that it will be inherited along > with one of several other classes that each define certain > functionality. It defines method_x, which it assumes will also be > defined in the other class that MyMixin ends up getting inherited > with. For example, > > class MyMixin(object): > def method_x(self, a, b, c): > ... > > class BaseA(object): > def method_x(self, a, b, c): > ... > > class BaseB(object): > def method_x(self, a, b, c): > ... > > class BaseC(object): > def method_x(self, a, b, c): > ... > > class FooX(MyMixin, BaseA): > ... > > class FooY(MyMxin, BaseB): > ... > > class FooZ(MyMixin, BaseC): > ... > > This all appears fine at first, but there is a problem: Each Foo's > method_x must call the method_x of MyMixin as well as the method_x of > each respective Foo's second base class. One cannot simply call > FooN.method_x, because that will only call MyMixin.method_x and not > that of the other base. > > One might be tempted to amend MyMixin's method_x so that it calls the > parent's method_x before doing anything else: > > class MyMixin(object): > def method_x(self, a, b, c): > super(MyMixin, self).method_x(a, b, c) > ... > > ...but of course, that will fail with an AttributeError because > MyMixin's only superclass is object, which does not have a method_x. > > The only way I can think to solve the problem would be to implement a > method_x for each Foo that calls the method_x for each of the bases: > > class FooX(MyMixin, BaseA): > def method_x(self, a, b, c): > MyMixin.method_x(self, a, b, c) > BaseA.method_x(self, a, b, c) > > class FooY(MyMxin, BaseB): > def method_x(self, a, b, c): > MyMixin.method_x(self, a, b, c) > BaseB.method_x(self, a, b, c) > > class FooZ(MyMixin, BaseC): > def method_x(self, a, b, c): > MyMixin.method_x(self, a, b, c) > BaseC.method_x(self, a, b, c) > > The problem with this solution is that method_x has to be explicitly > created for each Foo, even though they all do just about the same > thing, which kind of defeats the purpose of using multiple inheritance > in this situation. Besides that, I just don't like it! > > So, does anyone have an idea about how to remedy this, or at least > work around it?
Hopefully I've interpreted your requirement correctly. In this particular case a workaround is to use super() in your base classes and then have your concrete classes inherit from the base *before* the mixin: class MyMixin(object): def method_x(self, a, b, c): print "MyMixin" class BaseA(object): def method_x(self, a, b, c): print "BaseA" super(BaseA, self).method_x(a, b, c) class FooX(BaseA, MyMixin): pass FooX().method_x(1, 2, 3) BaseA MyMixin And if you want to define method_x() in FooX, then simply have that use super() as well. -- http://mail.python.org/mailman/listinfo/python-list