简体   繁体   English

如何在Python中将字符串(对象位置)的元组转换为对象字典

[英]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 help me please? 有人可以帮我吗? thanks! 谢谢!

You could use eval , which can be evil if your inputs are not safe: 您可以使用eval ,如果您输入的内容不安全,可能会很邪恶

>>> 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: 如果common.test.TestClass在当前名称空间中不存在,则会引发NameError

>>> 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 还有一个类似的问题: 如何动态加载Python类

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 ). Werkzeug的werkzeug.utils模块中有一个名为import_string的函数,该函数可以执行此操作( 在此处提供源代码 )。

(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: 因此,如果使用类似的import_string函数,则可以使用以下方法将元组转换为字典:

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". 使用“ 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. 但是,如果对象路径的一部分是尚未导入的子模块,则将无法正常工作-您必须“执行”一个导入语句才能检索该模块-Exec是eval的“更强”形式,这将受到支持语句,而eval仅保留用于表达式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM