selecting base class from user input

danielx danielwong at berkeley.edu
Mon Aug 14 17:40:06 EDT 2006


Jackson wrote:
> Maric Michaud wrote the following on 2006-08-14 01:26:
> > In [28]: class Animal(object) :
> >    ....:     _types = {}
> >    ....:
> >    ....:
> >
> > In [29]: class Worker(object) :
> >    ....:     def work(self) : print 'hard'
> >    ....:
> >    ....:
> >
> [snip]
> > What you are trying to achieve is more commonly done by agregation and
> > delegation :
> >
> > In [47]: class Lion(Animal) :
> >    ....:     def __init__(self, *classes) :
> >    ....:         self._objects = tuple(c() for c in classes)
> >    ....:     def isA(self, class_) :
> >    ....:         return class_ in (type(o) for o in self._objects)
> >    ....:     def __getattr__(self, name) :
> >    ....:         for obj in self._objects :
> >    ....:             try: return getattr(obj, name)
> >    ....:             except: pass
> >    ....:         raise AttributeError('not defined or found in objects "%s"' %
> > name)
> >    ....:
> >    ....:
> >
> > In [48]: Lion().work()
> > ---------------------------------------------------------------------------
> > exceptions.AttributeError                            Traceback (most recent
> > call last)
> >
> > /home/maric/<ipython console>
> >
> > /home/maric/<ipython console> in __getattr__(self, name)
> >
> > AttributeError: not defined or found in objects "work"
> >
> > In [49]: Lion().isA(Worker)
> > Out[49]: False
> >
> > In [50]: Lion(Worker).isA(Worker)
> > Out[50]: True
> >
> > In [51]: Lion(Worker).work()
> > hard
> >
>
> This is exactly what I am looking for.  However, I am not sure how to
> implement different Worker methods.  For example, a Lion might work
> differently than an Bee. In my example, the Lion would take a cat-nap
> while the Bee might do a dance.
>
> It seems that I would need to what kind of class called the work()
> method.  Is there a way to do that?

If all of your animals are supposed to be workers, maybe you should
declare your animal classes like this:

class Lion(Animal, Worker):
  def work(self): pass

Your Worker class might not have a work method (or it might have one
which does no work, pun intended), even though the methods it does have
depend on an instance being able to respond to a work call. Then, the
Worker class is like an "abstract" class in Java (cross yourselves).
This is an example of "delegation" which someone here has already
mentioned. In that case, users will most likely never instantiate
Worker, but none of the Worker code needs to be replicated, because
Lion (or whatever) is a subclass of Worker. This is one of the
"benefits" of OOP :P.

>
> Even if I could do that, it seems these various definitions of work
> should probably go into the class of the animal---so that Lion actions
> are all within the Lion class.  Thus, the Lion class should have its own
> work method, and the Bee class should have its own work method as well.
>  The problem with this is that every Lion can use the work method, when
> I really only work Workers to use the work method.
>
> I can picture another way of achieving this...have a list of
> occupations...which are booleans for each instance of the class.  Then
> the work() method will call only if the Worker boolean is True.  This
> should be sufficient...and the differing work methods would be in their
> respective classes. However, now the actual method names are not
> uniform---that is, it becomes a bookkeeping exercise to remember that
> when Worker is True, then the method to create is work(), that when
> Student is True, then the method to create is study().  So this
> procedure has its own problems too.  It seems like I am trading off
> hardships now.
>
> So here is what I am looking for:
>
> A single Worker class with a standardized set of method names. The

In Java (cross-ing ritual), you would create an interface, which
requires a work method. But this is Python :P. We just don't do that.
Search the following page for "easier to ask for forgiveness" and "look
before you leap" on this page (the glossary of Guido's Python
tutorial):

http://docs.python.org/tut/node18.html

> methods in the Worker class are dependent on the "superclass" (via
> aggregation and delegation, as shown above) of the worker.  That is, a
> Bee performs different actions when working than a Lion or a Human.  And
> finally, the occupations such that "not every Bee is a worker" and
> "there are some Workers which are Bees".
> 
> Thanks!




More information about the Python-list mailing list