On Sep 6, 10:48 pm, The Music Guy <music...@alphaios.net> wrote: > Sorry, that last code had a typo in it: > > #!/usr/bin/python > > def main(): > foox = FooX() > fooy = FooY() > fooz = FooZ() > > 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 BaseA(object): > > 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(object): > > pass > > class BaseC(object): > > def method_x(self, a, b, c): > super(BaseC, self).method_x(a, b, c) > print "BaseC.method_x(%s, %s, %s, %s)" % (repr(self), repr(a), > repr(b), repr(c)) > > class FooX(BaseA, MyMixin): > > 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(BaseB, MyMixin): > > pass > > class FooZ(BaseC, MyMixin): > > 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() > > Traceback (most recent call last): > File "foo.py", line 54, in <module> > main() > File "foo.py", line 8, in main > foox.method_x("I", "AM", "X") > File "foo.py", line 40, in method_x > super(FooX, self).method_x(a, b, c) > File "foo.py", line 24, in method_x > super(BaseA, self).method_x(a, b, c) > File "foo.py", line 18, in method_x > super(MyMixin, self).method_x(a, b, c) > AttributeError: 'super' object has no attribute 'method_x'
That's not what you did in your original post, though. Mixins should be listed first among bases, which is how you did it in your original post, and how it had to be in order for it to "just work" as I claimed. class FooX(MyMixin, BaseA) class FooY(MyMixin, BaseB) class FooZ(MyMixin, BaseC) If you are concerned that a base class might not define method_x (and therefore that the super call from MyMixin would fail), then there are a couple things you can do. First thing is to consider whether you ought to be using two method instead of one. Otherwise the easiest thing is to catch and ignore AttributeError from MyMixin's method_x: class MyMixin(object): def method_x(self, a, b, c): try: f = super(MyMixin, self).method_x except AttributeError: pass else: f(a,b,c) Note that you don't want to call the super inside the try block otherwise you risk catching spurrious AttributeErrors. This strategy might hide some typo-style errors with the base class, so if you're worried about that, another strategy would be to define another mixin which provides an empty method_x: class ProvideMethodX(self): def method_x(self, a, b, c): pass Then if BaseB does not define method_x, derive FooY from it like this: class FooY(MyMixin,ProvideMethodX,BaseB) Finally (and probably least confusingly) you could use separate mixins for bases that define method_x and those that don't. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list