Variable inheritance

Clarence Gardner clarence at netlojix.com
Tue May 22 17:52:40 CEST 2001


On Tue, 22 May 2001, kosh wrote:
>
>Yes that is a great use of MI. Using mixins for behavior is extremely 
>common in zope. It works very nicely be able to gain ACL capability by 
>inherting from the RoleManager or gain full persistance in the ZODB by 
>inheriting from Persist. Mixins work very nicely and I have used that 
>feature fairly commonly since it allows a better abstraction of various 
>workhorse functions from the design.

I may be able to clarify my particular situation by including more
context.  Here are some comments that have been made about my use
of multiple inheritance [though not about my question about how to
do the inheritance in a Pythonically-variable way :)]

[Roman Suzi]
>This example [not my printer scenario -- CG] is also artificial, because
>in reality we do not have so orthogonal properties.
In fact, the two base classes involved in my example are *completely*
orthogonal.

[Roman Suzi]
>Multiple inheritance says it bad design.
>Probably, you want a third container class, which
>will hold your Printer and OutputDevice classes
>and provide communication between them.
There *is* no communication between them...

[Magnus Lycka]
>The reasonable use of multiple inheritance is
>for so-called mixin-classes, that gives some
>particular behavior to a class.
>Both Printer.PSPrinter and OutputDevice.ToLP and
>are obviously real world objects.
Unless I've got my terminology wrong, my use of this *is* a mix-in class.
And the classes defined in module Printer are not real world objects.
My use of the name Printer may have thrown Magnus off.

Here's the deal.  I've got programs that want to produce printed output.
Depending on the invocation they may generate PostScript or plain text
(and now, PCL).  Also depending on the invocation, the output may in
fact be printed on paper, may be faxed, or emailed, or just stored in
a file.

The Printer module provides classes that implement an interface for
putting data on a virtual page; the OutputDevice module provides classes
that implement an interface for sending pages to devices.

Thus, (before the introduction of PCL), I have the following mix-in
classes that provide various combinations of these two independent notions:
    class TextToEmail(Printer.TextPrinter, OutputDevice.ToEmail):
    class TextToFile(Printer.TextPrinter, OutputDevice.ToFile):
    class TextToLP(Printer.TextPrinter, OutputDevice.ToLP):
    class PSToEmail(Printer.PSPrinter, OutputDevice.ToEmail):
    class PSToFile(Printer.PSPrinter, OutputDevice.ToFile):
    class PSToLP(Printer.PSPrinter, OutputDevice.ToLP):
    class PSToFax(Printer.PSPrinter, OutputDevice.ToFax):

Except for PSToLP, which I showed in my original post, the entire
implementation of each of these looks like this:
    class PSToEmail(Printer.PSPrinter, OutputDevice.ToEmail):
        def __init__(self, From, To, Relay, OptHdrs={}):
            OutputDevice.ToEmail.__init__(self, From, To, Relay, OptHdrs)
            Printer.PSPrinter.__init__(self)

The programs that use this have a small section at the top to decide
which mix-in to instantiate, then just get on with their printing to
that object.  This seems to me to be a very reasonable use of mix-in
(and hence, multiple inheritance).

-- Clarence




More information about the Python-list mailing list