Skipping a superclass

  • Thread starter Steven D'Aprano
  • Start date
S

Steven D'Aprano

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?
 
C

Chris Rebert

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
 
M

Miles Kaufmann

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top