tags:

views:

150

answers:

2

Hi,

Can anyone tell me how to bind to specific child class at run time in the following code? I want mCar instance in the following example redirect to class Truck or Compact according to command line options?

class Car(object):
    pass

class Truck(Car):
    pass

class Compact(Car):
    pass

and a instance of Car

mCar = Car()
+4  A: 

You mean like this?

car_classes = {
'car'     : Car,
'truck'   : Truck,
'compact' : Compact
}

if __name__ == '__main__':
    option = sys.argv[1]
    mCar = car_classes[option]()
    print 'I am a', mCar.__class__.__name__
GHZ
Hi, GahooaI think it should work in some cases. I am curious if there other ways like "typecasting" or change "__class__" in Car::__init__()Thanks
WuJanJai
Well you could use a class factory or even __metaclass__ http://en.wikibooks.org/wiki/Python_Programming/MetaClassesbut unless you really need it, it's likely to be overkill.
GHZ
Hi, GHZThanks for the pointer. That's exactly what I need.
WuJanJai
+1  A: 

As a side note, while not particularly recommended, it IS possible to assign a different value to self.__class__ -- be that in __init__ or anywhere else. Do notice that this will change the lookups for class-level names (such as methods), but per se it will not alter the instance's state (nor implcitly invoke any kind of initialization -- you'll have to do it explicitly if you need that to happen)... these subtleties are part of why such tricks are not particularly recommended (along with the general cultural bias of Pythonistas against "black magic";-) and a "factory function" (which in especially simple cases can be reduce to a dict lookup, as in GHZ's answer) is the recommended approach.

Alex Martelli
Thanks a lot for the explanation. The assignment of self.__class__ is what I saw in a third party code. But it looks to me that it needs to be delt with very carefully, as what you mentioned.
WuJanJai