Friday, February 6, 2009

creating an instance of a python class given the class' name as a string

Last week I was attempting to make a scalable test framework in python which dynamically loads in python files which extend a known base class. I ran into problems trying to create instances of each test class, it seemed like new.classobj or instance should be able to satisfy my needs, but they only overwrote the class I was trying to load (they were in fact too dynamic/useful).

Was half-trying to figure this out for a day or two, finally found a solution at http://mail.python.org/pipermail/python-list/2004-April/257367.html
I don't care for it much, but it seems to get the job done, and makes sense on an implementation as well as a python-philosophy level.

The example given was

>>> class A:
... def __init__(self, id):
... self.id = id
... def getID(self):
... print self.id
...
>>> oa1 = globals()['A'](12345)
>>> oa1
<__main__.a>
>>> oa1.getID()
12345

along with a valid note regarding the inherent kludge/betrayal/misconception in tying names to objects.

----

A much more satisfying solution for my particular problem appeared shortly after, while experimenting with what shows up in globals().

With the following directory structure/files:

./script.py # runner class
./test.py # template class for tests
./tests/ # test files directory
/test1.py # test class



# Other code loads directory contents and iterates
# Variables replaced with contents for clarity
# Note that "./" and "/" around "tests" are only there for completeness
>>> import sys
>>> sys.path.append("./tests/")
>>> t = __import__("test1")
>>> t_class = t.__dict__["test1"]
>>> t_inst = t_class()