[AstroPy] Coding Guidelines draft (comments encouraged)

Erik Bray embray at stsci.edu
Mon Jul 18 12:00:22 EDT 2011


On 07/18/2011 07:43 AM, Erik Tollerud wrote:
> I agree with the view that "multiple inheritance should be avoided
> when possible" is a pretty good guideline.  But Chris identifies the
> fact that there really is call for separate classes - the use case
> Chris identifies seem to generally go by the name of "mixins."
> Fortunately, these are exactly the cases where super() is unnecessary
> even in __init__; if the classes are unrelated in functionality, you
> can freely just do "SuperClass1.__init__self()" and
> "SuperClass2.__init__(self)" without worrying that they will interact
> some way.

I also agree with the "multiple inheritance should be avoided when 
possible" guideline.  But what does this really mean?  It's possible I 
could rewrite my project to not use object-oriented patterns at all, 
thus avoiding any "need" for multiple inheritance, so it's not really a 
useful guideline.

> So with this in mind, it's not clear to me what's best to put in the
> guidelines (if anything) on the topic.  Perhaps "multiple inheritance
> should be avoided, aside from use of mixins",and define mixins as
> superclasses that provide extra functionality or support without
> overlapping on the other superclasses? Or "multiple inheritance where
> superclasses are derived from the same higher superclass should be
> avoided" (i.e. no diamond-inheritance structures, trusting that they
> won't overlap if they don't have the same supers)?

Mixins are probably the best use case for multiple inheritance, but 
they're not the only one.  PyFITS uses multiple inheritance extensively. 
  I'll admit that in some places it gets confusing, and I would like to 
try to simplify it more than I already have.  But the existing 
implementation tracks with the FITS specification itself, and is working 
pretty well.  Here's an example of how it's used in PyFITS:

FITS has a notion of 'extension HDUs' that have some different 
properties from non-extension HDUs, though most HDUs in a FITS file are 
extensions.  All extension HDU classes inherit from an ExtensionHDU 
class which has its own __init__() and a few other methods.

There are two types of HDUs in FITS that can contain an image: a Primary 
HDU and an Image Extension HDU.  The former is *not* an extension HDU, 
though they both work mostly the same with respect to handling their 
image data.  PyFITS implements all image-related code in an ImageBaseHDU 
class.  The PrimaryHDU class inherits only from ImageBaseHDU, while the 
ImageHDU class inherits from both ImageBaseHDU and ExtensionHDU.  So 
this part of the class hierarchy looks basically like this:

                     BaseHDU
                       /  \
                     /      \
                   /          \
                 /              \
           ImageBaseHDU     ExtensionHDU
               / \             /
             /     \         /
         PrimaryHDU  \     /
                       \ /
                    ImageHDU

So there's a good example of diamond inheritance structure in real life 
that's working, with additional branches off of it.  A similar hierarchy 
exists for table-like HDUs (GroupHDUs, AsciiTableHDUs, and 
BinTableHDUs).  Furthermore, not all of these classes take the same 
arguments in their __init__()s, but this is handled by accepting **kwds 
in all the __init__()s.

So while I agree that multiple inheritance should be avoided, the 
question is how strong is this statement intended to be?  I would say 
that it should be avoided unless you _really_ know what you're doing, 
which is a statement I would make about multiple inheritance in any OO 
language.

Thanks,
Erik



More information about the AstroPy mailing list