Variable inheritance

Alex Martelli aleaxit at yahoo.com
Tue May 22 06:06:05 EDT 2001


"Oleg Broytmann" <phd at phd.fep.ru> wrote in message
news:mailman.990520450.24478.python-list at python.org...
> On Tue, 22 May 2001, Roman Suzi wrote:
> > I was always very irritated when somebody proposed something like
> >
> > class Line(Point):
> >   ...
> >
> > just because line could be made of two points.
>
>    Of course. Now THIS is bad design. Line IS NOT a point, hence, no
> inheritance should occur. Line CONSISTS of two point, so
>
> class Line:
>    def __init__(self, p1, p2):
>       self.p1 = p1
>       self.p2 = p2

Yep, obvious.


>    But grey mouse DOES NOT "contains" grey color. The mouse IS really grey
> thing, hence I used inheritance.

Not a good example IMHO.  This is a typical misuse of 'IS', the
kind that got Korzibsky to rant justifiedly against 'the IS of
identity'.  Good examples are those where something *BEHAVES*
in a certain way.  _Behavior_ is chiefly what you want to use
inheritance for, rather than "identity".  Don't be misled by
reflection that in some natural language you might say 'A is B'
into thinking that you have a good case for inheritance -- the
verb "to be" is overloaded and overused in natural language and
most people's thinking, most often inappropriately:-).

The case for mix-in has already been made repeatedly on this
thread, and that tends to be a case of 'pure behavior' -- often
bereft of "application concept-space" correspondence.  But it's
often the case that behavior DOES correspond to concepts in the
application concept-space, too.

A typical example is what the gang of 4 call the 'template'
design pattern -- a higher-level method that organizes things
by calling lower-level ones in appropriate ways.  You have
to inherit from a template to supply the lower-level methods
most sensibly and conveniently.  E.g.:

class IterativeComputation:
    def start_iteration(self): pass
    def postprocess(self, value): return value
    def compute(self): raise NotImplementedError
    def iterate(self, maxSteps=1000, epsilon=0.1e-10):
        self.start_iteration()
        result = self.compute()
        for i in range(maxSteps):
            nextvalue = self.compute()
            var = abs((nextvalue-result)/result)
            if var<epsilon: break
            result = nextvalue
        return self.postprocess(nextvalue), var, i


Alex






More information about the Python-list mailing list