How to transform tuple of string(object locations) to dictionary of objects in python
I would like to transform a tuple:
TEST_CLASSES = (
'common.test.TestClass',
)
to
TEST_CLASSES = {
'test': common.test.TestClass,
}
How to make a dictionary is simple but I have a problem with conversion from string to object. Could anybody h开发者_开发百科elp me please? thanks!
You could use eval
, which can be evil if your inputs are not safe:
>>> import os
>>> eval('os.path.join')
<function join at 0x00BBA2B8>
if the common.test.TestClass
doesn't exist in the current namespace a NameError
will be raised:
>>> eval('math.isnan')
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
eval('math.isnan')
File "<string>", line 1, in <module>
NameError: name 'math' is not defined
As far as I understand, you try to get class by its string name. There was a similar question: How to dynamically load a Python class
You can't directly "convert from string to object" (though in a technical sense, strings are objects), but you can use a function that can import the objects for you. Werkzeug's werkzeug.utils
module has a function in it named import_string
that does just that (source here).
(I'm assuming that the objects you want are to be imported from modules.)
So, if you use a similar import_string
function, you can transform the tuple to a dictionary with this:
test_classes = {}
for path in TEST_CLASSES:
obj = import_string(path)
test_classes[obj.__module__.split('.')[-1]] = obj
The straightforward and oftenly not recomended way there is to use "eval".
Simply doing:
obj = eval('common.test.TestClass')
Will give you the object as specified on the string.
Other, more elegant ways, would involve querying each object on the chain for the next attribute - you can avoud eval in this way:
string = 'common.test.TestClass'
# this retrieves the topmost name, supposedly a module, as an object:
obj = globals()[string.split(".")[0]]
# And retrieve each subobject object therein:
for part in string.split(".")[1:]:
obj = getattr(obj, part)
If part of your object path is an yet not-imported submodule, though, this won't work - You'd have to "exec" an import statement to retrieve the module - Exec being a "stronger" form of eval, wich supports statements, while eval is reserved only for expressions.
精彩评论