Variable inheritance

Alex Martelli aleaxit at yahoo.com
Tue May 22 11:54:45 EDT 2001


"Samuel A. Falvo II" <kc5tja at dolphin.openprojects.net> wrote in message
news:slrn9gkvat.5c8.kc5tja at dolphin.openprojects.net...
> On Tue, 22 May 2001 12:23:43 +0400 (MSD), Roman Suzi wrote:
> >This is indeed a contra-example and is a bad design, because
> >it leeds to combinatorically bloated code, in which you need
> >M*N*K... classes to have all kinds of objects.
>
> Yes.  But unless the user (versus the programmer) is responsible for
> dynamically creating objects of various types, this simply isn't a
problem.
>
> If the user DOES have some involvement with the creation of objects, then
> it's clear that delegation and aggregation are the only reasonable
solution
> (or, at least, the easiest to implement and maintain).

Not necessarily so, in Python.  Say the user chooses
'feature-sets' he wants by 'copying' the feature-set
names in a GUI from a list to another, e.g. by drag
and drop; he may also arbitrarily reorder the list
of feature sets he has chosen in terms of priority --
if two chosen feature-sets both provide a way to
handle a certain behavior, the user gets to choose
which one takes precedence.  This might be excellent
as a user-interface in a bridge-bidding system to
choose sets of bidding conventions, for example.  When
done, the user writes in a name for the new thingy in
an appropriate text-field, and clicks the "Create"
button.

OK, so now we have a tuple of 'feature-sets' (classes)
whose features the user desires in the object he is
creating.  What is the best way to mix them?

Why, multiple inheritance, of course -- what else?

class ObjectCreator:
    class Starter:
        def __init__(self, name):
            self.name, self.uniq = name
            for b in self.__class__.__bases__:
                getattr(b,'__init__',lambda x:0)(self)
    def __init__(self):
        self.classRegistry = {}
        self.nameRegistry = {}
    def create(self, name, basestuple):
        if not self.classRegistry.has_key(basestuple):
            class Temp((Starter,)+basestuple): pass
            self.classRegistry(basestuple) = Temp
        uniq = 0
        while self.nameRegistry.has_key((name,uniq)):
            uniq += 1
        name = (name,uniq)
        result = self.classRegistry[basestuple]('%s_%s'%(name,uniq))
        self.nameRegistry[name] = result
        return result

I don't see how aggregation and delegation would be easier
to implement and maintain than this simple framework.  You
can add new potential base-classes anytime, in fact updating
the UI is more than a chore than updating the underlying
engine (since the latter doesn't need to be updated:-).

All the work you would have to code in delicate boilerplate
in Python for the delegation is handled by Python itself
as it looks for methods and other attributes of the objects
so created.  And isn't this exactly as it should be?


Python gives us a flexible, solid, powerful code reuse
mechanism in its inheritance structure.  I don't see why
one shouldn't take full advantage of it just because of
mistaken (or at least SERIOUSLY debatable:-) philosophical
ideas on the role of taxonomy in classification!-)


Alex






More information about the Python-list mailing list