Welcome, guest | Sign In | My Account | Store | Cart

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>

Python, 41 lines
 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.

3 comments

Hamish Lawson 17 years, 5 months ago  # | flag

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:

def getObject(cond):
    if cond:
        cls = A
    else:
        cls = B
    return cls()

If you need a multiway decision you can use a dictionary that has the candidate classes as its values.

Peter van Kampen (author) 17 years, 5 months ago  # | flag

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.

Harry Fuecks 17 years ago  # | flag

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;

class Dispatcher:
    def _dispatch(self, method, params):
        # XML-RPC request method: MyClass.someMethod
        handler, method = string.split(method,'.',1)

        # Perhaps dynamically __import__() here...

        # Get the class
        clas = globals()[handler]

        # Get the method in the class
        func = class.__dict__[method]

        # Create the object
        obj = clas()

        # Shift the obj instance into the start of the params
        params.insert(0,obj)

        # Call the function...
        apply(func,params)
Created by Peter van Kampen on Thu, 10 Jun 2004 (PSF)
Python recipes (4591)
Peter van Kampen's recipes (4)

Required Modules

  • (none specified)

Other Information and Tasks