Kent Johnson said unto the world upon 2005-03-18 07:35:
Brian van den Broek wrote:

Kent Johnson said unto the world upon 2005-03-17 20:44:


The multiple inheritance from MyNode and Toolkit.NodeX is a smell. I guess you do this because you want to override methods of Toolkit.Node as well as Toolkit.NodeX, or add methods to both MyNode1 and MyNode2? I would look for another way to do this, maybe using some kind of helper class to hold some common functions?

<SNIP Brian's original rational for using multiple inheritance>

Are you suggesting the multiple inheritance is always a smell?


No. Some people would agree with that - e.g. the creators of Java - but I have seen many times where
MI is useful. Usually it is to combine a primary base class with a mixin - a class that adds
functionality orthogonal to that of the base class, or that modifies a carefully chosen set of base
class methods.
http://c2.com/cgi/wiki?MultipleInheritanceIsNotEvil
http://c2.com/cgi/wiki?MixIn

<SNIP GUI example>

BUT there are some clear gotchas to MI. They mostly arise when you inherit from classes that
themselves have a common base class. The "diamond" pattern is the usual example:


class A:
  ..

class B(A):
  ..

class C(A):
  ..

class D(B, C):
  ..

Now you can have all kinds of fun (i.e. subtle bugs and confusion) if A, B, C and D have methods in
common and if they want to call the methods of their base classes. One of the changes is new-style
classes (the addition of super() and a change to the "method resolution order") was made to address
some deficiencies in how old-style classes handle this situation.


So, calling this a code smell is probably not the right term. It's more like a red warning light and
klaxon :-) You just don't want to do this without understanding the issues.


See http://www.python.org/doc/2.2.3/whatsnew/sect-rellinks.html#SECTION000330000000000000000 and PEP
253 for details or google "diamond multiple inheritance"


Well, if I let failure of understanding stop me, I'd still be writing nothing but DOS batch files :-) But, point taken.

Thanks for the links. I'd read about the diamond pattern in the past, but at a time before I'd ever written a class to call my own. Pushed by this discussion, and with a problem context to read the texts through, I re-read the dead-tree sources I have at hand. For anyone following along, the relevant section of the Nutshell (p 88ff) makes a good deal of sense of this. Learning Python 370ff is also on point.


I'll google, but my only grasp of the meaning of "helper class" is what comes from intuition.


For example, instead of subclassing Toolkit.Node, could you define the extra methods in another
class. Then your NodeX subclasses can inherit from Toolkit.NodeX and NodeHelper. e.g.


class MyNodeHelper:
  def doSomethingSpecial(self):
    # does something with a Toolkit.Node

class MyNode1(Toolkit.Node1, MyNodeHelper):
  ..

This is an example of a mixin class.


OK, that makes sense. The effect, as I understand it, is to put the new behaviour common to NodeX classes in a separate bundle for safety, thereby making the MRO more transparent. And, as I learned when I used to work road construction, safety first! :-)

Thanks for the help, Kent.

Best to all,

Brian vdB

_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to