Skipping a superclass
I have a series of subclasses like this: class A(object): def method(self, *args): print Lots of work gets done here in the base class class B(A): def method(self, *args): print A little bit of work gets done in B super(B, self).method(*args) class C(B): def method(self, *args): print A little bit of work gets done in C super(C, self).method(*args) However, the work done in C.method() makes the work done in B.method() obsolete: I want one to run, or the other, but not both. C does need to inherit from B, for the sake of the other methods, so I want C.method() *only* to skip B while still inheriting from A. (All other methods have to inherit from B as normal.) So what I have done is change the call to super in C to super(B, self) instead of super(C, self). It seems to work, but is this safe to do? Or are there strange side-effects I haven't seen yet? -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Skipping a superclass
On Sun, Aug 2, 2009 at 5:36 AM, Steven D'Apranost...@remove-this-cybersource.com.au wrote: I have a series of subclasses like this: class A(object): def method(self, *args): print Lots of work gets done here in the base class class B(A): def method(self, *args): print A little bit of work gets done in B super(B, self).method(*args) class C(B): def method(self, *args): print A little bit of work gets done in C super(C, self).method(*args) However, the work done in C.method() makes the work done in B.method() obsolete: I want one to run, or the other, but not both. C does need to inherit from B, for the sake of the other methods, so I want C.method() *only* to skip B while still inheriting from A. (All other methods have to inherit from B as normal.) So what I have done is change the call to super in C to super(B, self) instead of super(C, self). It seems to work, but is this safe to do? Or are there strange side-effects I haven't seen yet? Barring some true weirdness in super(), I don't /think/ so. It obviously works fine in the single-inheritance case, and (after some brute-force testing) the only permitted multiple inheritances involving C and (A or B) always have C ahead of B in the MRO (method resolution order). The fact that you're wanting to bypass a superclass method might suggest however, that your hierarchy could be structured better. Have you considered moving B.method() into another, new class (e.g. newB) which subclasses B? Then C can inherit from B without inheriting the unwanted method, while B's functionality still exists, just under a new name (newB). Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Skipping a superclass
On Aug 2, 2009, at 5:36 AM, Steven D'Aprano wrote: I have a series of subclasses like this: class A(object): def method(self, *args): print Lots of work gets done here in the base class class B(A): def method(self, *args): print A little bit of work gets done in B super(B, self).method(*args) class C(B): def method(self, *args): print A little bit of work gets done in C super(C, self).method(*args) However, the work done in C.method() makes the work done in B.method() obsolete: I want one to run, or the other, but not both. C does need to inherit from B, for the sake of the other methods, so I want C.method() *only* to skip B while still inheriting from A. (All other methods have to inherit from B as normal.) This might not be applicable to the larger problem you're trying to solve, but for this sample, I would write it as: class A(object): def method(self, *args): self._method(*args) print Lots of work gets done here in the base class def _method(self, *args): pass # or perhaps raise NotImplemented class B(A): def _method(self, *args): print A little bit of work gets done in B class C(B): def _method(self, *args): print A little bit of work gets done in C So what I have done is change the call to super in C to super(B, self) instead of super(C, self). It seems to work, but is this safe to do? Or are there strange side-effects I haven't seen yet? In a diamond-inheritance situation, you may end up skipping methods besides just B.method(). -Miles -- http://mail.python.org/mailman/listinfo/python-list