selecting base class from user input
danielx
danielwong at berkeley.edu
Mon Aug 14 17:07:05 EDT 2006
Jackson wrote:
> Thanks for the reply.
>
> danielx wrote the following on 2006-08-13 19:49:
> > Is your declaration of ABC supposed to have some_super as one of the
> > base classes? Your constructor has some_super as a parameter. What is
> > this supposed to mean in light of the declaration for ABC?
>
> Indeed, my goal is to have the base class of ABC determined dynamically
> via a parameter passed into the constructor.
> >
> > If you are trying to customize the base class of ABC by passing an
> > argument to the constructor of ABC, you should probably reconsider. If
> > constructing one instance of ABC can change ABC (the class) itself,
> > then the behavior of other instances will be affected as well. No
> > programmer can stay sane if he creates instances of a class that could
> > suddenly change its behavior (due to someone else's code).
>
> Fortunately, the ABC class is not very useful. In fact, it was mostly
> just to be used to store particular examples of the user-specified base
> class. So all method calls would be from the base class only.
>
> >
> > What you could do instead is to create a function which constructs
> > classes based on the arguments it recieves. Then, you'll be able to
> > create instances of the generated classes (all this meta-thinking is
> > huring my brain ;). I am talking about something like this:
> >
> > def createClass(name, base):
> > exec "class %s(%s): pass" % (name, base)
> > return eval( "name" )
>
> In fact, this is exactly what I ended up doing.
>
> def example(base):
> if base == SomeClass:
> # call SomeClass.__init__(self)
> # build example as it would look in SomeClass
>
> elif base == SomeOtherClass:
> # call SomeOtherClass.__init__(self)
> # build example as it would in SomeOtherClass
>
> > Can you please tell us why you are doing this? My curiosity is killing
> > me!
> >
>
> So here is a good example:
>
> I have 4 classes:
>
> Lion(Animal):
> Ant(Animal):
> Bee(Animal):
> Human(Animal):
>
> which are all subclasses of some superclass called Animal. Now I want
> to define an occupation. For example, Worker. A worker can exist as any
> of the 4 classes above. Their constructors are different and I might
> want to add certain features.
>
> My first thought was to create a class called "Worker" and have the base
> class determined by a variable which is passed into the constructor.
What you should keep in mind though, is the "is-a" relationship that
subclasses are supposed to have with their parents. "worker is a lion"
does not make sense. What you want instead is LionWorker. You'll end up
doing only a little more typing than if you had a general Worker class,
but I don't think it will be much more.
If your *Worker classes have really simple bodies, you might be able to
automate the creation of your *Worker classes by doing something like
the createClass function (ie, by creating the classes dynamically
instead of using the class statement).
I also discovered another way to dynamically create classes, described
in this article (the article talks about other things as well):
http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html
I'm not sure if this will help you, but it's definitely interesting.
> Most of the method calls will come from the Animal superclass anyway,
> but some method calls might come from the Lion class, for example.
>
> 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.
>
> So for example (again, I know what I am typing doesn't actually work)...
>
> Worker(some_animal):
> def __init__(self,some_animal):
> # change the base class to some_animal
>
> if some_animal == Lion:
> # give the lion a big mane
>
> if some_animal == Ant:
> # make the ant dumb
>
> if some_animal == Bee:
> # make the bee know how to dance
>
> if some_animal == Human
> # give the human a hardhat
>
> def work(self, hours):
> # tell the animal to work for the specified number of hours
> if some_animal == Lion:
> self.cat_nap(hours)
> if some_animal == Ant:
> self.walk_back_and_forth(hours)
> if some_animal == Bee:
> self.buzz_and_dance(hours)
> if some_animal == Human:
> self.use_hammer_on_coworker(hours)
> # notice, a Human does not have a cat_nap method
>
> def take_lunch(location):
>
> ....
>
> and so on. So the thought is that a Worker can exist in many different
> forms: as a lion, as an ant, as a bee, and as a human. And I might want
> a single worker class that represents them all.
>
> Hopefully this makes sense.
>
> > Another meta-thought: Hopefully I've beaten everyone else to the punch
> > about that question. Is it just me, or will a reply with such a
> > question always tell the original poster that what he wants to do MUST
> > be flawed? I hope I have been gentler than this.
> >
>
> :-) There is no need to be too gentle. We are all here to learn (or
> help). So I am fairly happy with the def solution...any comments on
True, but that doesn't mean you have to stand a rude response. I'm just
hoping for a little more courtesy than what I've seen.
> this? But a Worker is an noun, and it seems like the proper way to do
> this is to make the Worker into a class...so that I can define methods
> like "work", "take_lunch", etc. However, I have no idea how I should do
> this. Perhaps someone can recommend a procedure.
>
> thanks.
More information about the Python-list
mailing list