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?



The adding methods rationale. I never instantiate Node, instead I use it for behaviour common to Node1 and Node2. Toolkit.py gives specialized methods to both Node1 and Node2. I need MyNode1 and MyNode2 (the Application.py versions) to have all the powers of the Toolkit.Node1 and Node2 classes, plus some new powers in common, and some new powers defined separately. That is the sort of thing I had understood multiple inheritance to be for -- but my understanding is about as shaky as an addict in withdrawal :-)


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

For example in a GUI toolkit you might have an Observable add-in that gives a 
class means to
remember and broadcast to listeners. In the Python library there are 
SocketServer mixins that create
a threaded server.

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"


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.

Kent


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

Reply via email to