selecting base class from user input

Maric Michaud maric at aristote.info
Mon Aug 14 04:26:09 EDT 2006


Le lundi 14 août 2006 09:33, Jackson a écrit :
> Now I realize this would drive a programmer crazy...because a Lion might
> have a roar() method whereas a Human might have a holler() method. But
> so long as the user knew which argument they passed in, it shouldn't be
> too difficult to keep track of it.

There are many problems if you go that way.
One implementation could be :

In [28]: class Animal(object) :
   ....:     _types = {}
   ....:
   ....:

In [29]: class Worker(object) :
   ....:     def work(self) : print 'hard'
   ....:
   ....:

In [30]: def createLion(*classes) :
   ....:     def roar(self) : print "roar"
   ....:     if not classes in Animal._types :
   ....:         Animal._types[classes] = type('Lion', (Animal,) + classes, 
{'roar' : roar})
   ....:     return Animal._types[classes]()
   ....:

In [31]:

In [31]: createLion().roar()
roar

In [32]: type(createLion())
Out[32]: <class '__main__.Lion'>

In [33]: type(createLion()) is type(createLion())
Out[33]: True

In [34]: createLion(Worker).roar()
roar

In [35]: createLion(Worker).work()
hard

In [36]: type(createLion(Worker))
Out[36]: <class '__main__.Lion'>

In [37]: type(createLion(Worker)) is type(createLion(Worker))
Out[37]: True

In [38]: Animal._types
Out[38]:
{(): <class '__main__.Lion'>,
 (<class '__main__.Worker'>,): <class '__main__.Lion'>}

In [39]: type(createLion(Worker)) is type(createLion())
Out[39]: False

The main problems are : first, your classes definition are hidden, second 
there is no real Lion class to test, say isinstance(createLion(toto), Lion), 
this can be misleading.

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



-- 
_____________

Maric Michaud
_____________

Aristote - www.aristote.info
3 place des tapis
69004 Lyon
Tel: +33 426 880 097



More information about the Python-list mailing list