Inheritance and Design Question

I

imageguy

I have an object the I would like to use as a base class. Some of the
methods I would like to override completely, but others I would simply
like to call the base class method and use the return value in the
child method. The purpose here is to eliminate the duplication of
valuable code in the parent, when I really just need the child to
operate of a results of the parent.

Consider the following two classes;

class Parent(object):
def process(self, value):
retval = "Parent.result('%s')" % value
return retval

class Child(Parent):
def __init__(self):
Parent.__init__(self)

def process(self, value):
retval = "Child.result('%s')" % super(Child, self).process
(value)
return retval

So ....

foo = Child()
print foo.process('the value')
IS there another pattern or idiom that would accomplish this?
This seems a bit 'smelly' to me. Also seems almost the inverse of
decorators, but I am not sure decorators would be appropriate in this
case.

Any help suggestions would be appreciated.

g.
 
M

Matimus

I have an object the I would like to use as a base class.  Some of the
methods I would like to override completely, but others I would simply
like to call the base class method and use the return value in the
child method.  The purpose here is to eliminate the duplication of
valuable code in the parent, when I really just need the child to
operate of a results of the parent.

Consider the following two classes;

class Parent(object):
    def process(self, value):
        retval = "Parent.result('%s')" % value
        return retval

class Child(Parent):
    def __init__(self):
        Parent.__init__(self)

    def process(self, value):
        retval = "Child.result('%s')" % super(Child, self).process
(value)
        return retval

So ....

foo = Child()
print foo.process('the value')


IS there another pattern or idiom that would accomplish this?
This seems a bit 'smelly' to me.  Also seems almost the inverse of
decorators, but I am not sure decorators would be appropriate in this
case.

Any help suggestions would be appreciated.

g.

From what you have shown, there really is no _good_ reason to use
inheritance at all. Just delegate (which is the decorator pattern,
different from function decorators).

class Inner(object):
def process(self, value):
retval = "Parent.result('%s')" % value
return retval

class Outer(object):
def __init__(self, inner):
self._inner = inner

def process(self, value):
retval = "Outer.result('%s')" % self._inner.process(value)
return retval

This is a silly example, but if you can get the same thing done
without creating a direct dependence between classes then don't. You
will have to construct outer and pass it inner somewhere. If that is a
problem, then just make a factory. In python I implement factories as
just functions most of the time.

The above also encourages reuse. Now you have a decorator that could
be used anywhere.

Matt
 
T

Terry Reedy

imageguy said:
I have an object the I would like to use as a base class. Some of the
methods I would like to override completely, but others I would simply
like to call the base class method and use the return value in the
child method. The purpose here is to eliminate the duplication of
valuable code in the parent, when I really just need the child to
operate of a results of the parent.

Consider the following two classes;

class Parent(object):
def process(self, value):
retval = "Parent.result('%s')" % value
return retval

class Child(Parent):
def __init__(self):
Parent.__init__(self)

Delete this and the parent __init__ is called directly.
def process(self, value):
retval = "Child.result('%s')" % super(Child, self).process
(value)
return retval

super() was designed for multiple inheritance. The only reason I know
to use it with single inheritance it to save a
global-search-and-replace_with_confirmation if you change the name of
the parent or change parents. Unless I really anticipated such
contigencies, I would probably write Parent.process(self, value).

tjr
 
S

Steven D'Aprano

super() was designed for multiple inheritance.

Surely you mean that super() was designed for *inheritance*, multiple or
singular? Working with single inheritance is part of the design, not an
accident of implementation.

The only reason I know
to use it with single inheritance it to save a
global-search-and-replace_with_confirmation if you change the name of
the parent or change parents.

How about these reasons?

(1) If you're subclassing something you didn't write, you might not know
whether it uses multiple or single inheritance.

(2) Even if you do know, you shouldn't care what the implementation of
the parent is. Using super() allows you to be agnostic about the
implementation, while calling Parent.method() directly ties you to a
specific implementation.

(3) Your callers may want to inherit from your class, and if you fail to
use super, you are condemning them to potentially buggy code if they use
multiple inheritance.

(4) Using super() is no harder than avoiding super(). It takes a few
extra characters to type, at worst:

super(MyClass, self).method(args)
Parent.method(self, args)
 
A

Andre Engels

I have an object the I would like to use as a base class.  Some of the
methods I would like to override completely, but others I would simply
like to call the base class method and use the return value in the
child method.  The purpose here is to eliminate the duplication of
valuable code in the parent, when I really just need the child to
operate of a results of the parent.

Consider the following two classes;

class Parent(object):
   def process(self, value):
       retval = "Parent.result('%s')" % value
       return retval

class Child(Parent):
   def __init__(self):
       Parent.__init__(self)

   def process(self, value):
       retval = "Child.result('%s')" % super(Child, self).process
(value)
       return retval

So ....

foo = Child()
print foo.process('the value')

IS there another pattern or idiom that would accomplish this?
This seems a bit 'smelly' to me.  Also seems almost the inverse of
decorators, but I am not sure decorators would be appropriate in this
case.

I think I would split out the calculation into two methods in this case:

class Parent(object):
def process_essential(self,value):
retval = "Parent.result('%s')" % value
return retval

def processs(self,value):
return process_essential(value)

class Child(Parent):
def process(self,value):
retval = "Child.result('%s')" % process_essential(value)
return retval
 
C

Carl Banks

I have an object the I would like to use as a base class.  Some of the
methods I would like to override completely, but others I would simply
like to call the base class method and use the return value in the
child method.  The purpose here is to eliminate the duplication of
valuable code in the parent, when I really just need the child to
operate of a results of the parent.

Consider the following two classes;

class Parent(object):
    def process(self, value):
        retval = "Parent.result('%s')" % value
        return retval

class Child(Parent):
    def __init__(self):
        Parent.__init__(self)

    def process(self, value):
        retval = "Child.result('%s')" % super(Child, self).process
(value)
        return retval

So ....

foo = Child()
print foo.process('the value')


IS there another pattern or idiom that would accomplish this?
This seems a bit 'smelly' to me.  Also seems almost the inverse of
decorators, but I am not sure decorators would be appropriate in this
case.

I see nothing wrong with it, although if it is possible and convenient
to rename the base class method, as Andre Engels suggests, then that's
usually how I'd do it.

Sometimes it's not convenient to choose a different name for the base
class method, such as when you have several subclasses, most of which
don't override the method, but a few do. In that case I'd do it same
way as you did.

One thing that does smell is your use of both old-style base class
access (Parent.__init__(self)) and newer-style (super
(Child,self).process()) in the same class. Pick one method and stick
with it.


Carl Banks
 
J

Jean-Michel Pichavant

imageguy said:
I have an object the I would like to use as a base class. Some of the
methods I would like to override completely, but others I would simply
like to call the base class method and use the return value in the
child method. The purpose here is to eliminate the duplication of
valuable code in the parent, when I really just need the child to
operate of a results of the parent.

Consider the following two classes;

class Parent(object):
def process(self, value):
retval = "Parent.result('%s')" % value
return retval

class Child(Parent):
def __init__(self):
Parent.__init__(self)

def process(self, value):
retval = "Child.result('%s')" % super(Child, self).process
(value)
return retval

So ....

foo = Child()
print foo.process('the value')
Try this

class Parent(object):

def process(self, value):
retval = "%s.result('%s')" % (self.__class__.__name__, value)
return retval

class Child(Parent):
def __init__(self):
Parent.__init__(self)


foo = Child()
print foo.process('the value')
Of course you cannot see the inheritance in the result, but I'm assuming you wanted only the instance class to be displayed.

Jean-Michel
 

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,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top