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