开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜