[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