I sometimes want to create objects from various classes based on some condition (without using eval()). For example when parsing X(HT)ML files I want to handle some tags using specific classes. It is actually quite easy but I had a hard time finding out how to do that, no doubt due to my limited knowledge of python, so here's a simple example.
Edit: See also <a href="http://www.faqts.com/knowledge_base/view.phtml/aid/2635/fid/242">http://www.faqts.com/knowledge_base/view.phtml/aid/2635/fid/242</a>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | class A(object):
def __init__(self):
print 'This is A'
def foo(self):
print "foo"
class B(object):
def __init__(self):
print 'This is B'
def foo(self):
print "bar"
def getObject(cond):
if cond:
classname = 'A'
else:
classname = 'B'
object = globals()[classname]
return object()
myobject = getObject(1)
myobject.foo()
print dir(myobject)
print
a = A()
a.foo()
print dir(a)
print
myobject = getObject(0)
myobject.foo()
print dir(myobject)
print
b = B()
b.foo()
print dir(b)
|
Produces this output:
This is A foo ['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'foo']
This is A foo ['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'foo']
This is B bar ['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'foo']
This is B bar ['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'foo']
As you can see, and as far as I can tell, the results are identical.
You can specify the class directly rather than by name. Python classes can be passed around, so you can refer them to directly rather than by name:
If you need a multiway decision you can use a dictionary that has the candidate classes as its values.
This assumes you know the names of the classes in advance. I needed to be able to create objects from classnames that were only known at runtime. The example isn't very good I guess but I wanted to provide a simple example.
Call object method from string. Had a situation where I needed this for an XML-RPC server to dispatch calls. May be a smarter way to do it but couldn't find it;