【问题标题】:How to transform tuple of string(object locations) to dictionary of objects in python如何将字符串元组(对象位置)转换为python中的对象字典
【发布时间】:2010-02-09 11:47:20
【问题描述】:

我想转换一个元组:

TEST_CLASSES = (
   'common.test.TestClass',
)

TEST_CLASSES = {
   'test': common.test.TestClass,
}

如何制作字典很简单,但我在从字符串转换为对象时遇到了问题。有人可以帮我吗?谢谢!

【问题讨论】:

标签: python


【解决方案1】:

您可以使用eval,如果您的输入不安全,这可能是邪恶的

>>> import os
>>> eval('os.path.join')
<function join at 0x00BBA2B8>

如果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

【讨论】:

    【解决方案2】:

    据我了解,您尝试通过字符串名称获取类。有一个类似的问题:How to dynamically load a Python class

    【讨论】:

      【解决方案3】:

      您不能直接“从字符串转换为对象”(尽管在技术意义上,字符串是对象),但您可以使用可以为您导入对象的函数。 Werkzeug 的 werkzeug.utils 模块中有一个名为 import_string 的函数,它就是这样做的 (source here)。

      (我假设你想要的对象是从模块中导入的。)

      因此,如果您使用类似的import_string 函数,您可以使用以下方法将元组转换为字典:

      test_classes = {}
      for path in TEST_CLASSES:
          obj = import_string(path)
          test_classes[obj.__module__.split('.')[-1]] = obj
      

      【讨论】:

        【解决方案4】:

        直接且通常不推荐的方式是使用“eval”。

        简单地做:

        obj = eval('common.test.TestClass') 
        

        会给你字符串上指定的对象。

        其他更优雅的方法包括查询链上的每个对象以获取下一个属性 - 您可以通过这种方式避免 eval:

        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)
        

        如果您的对象路径的一部分是一个尚未导入的子模块,那么这将不起作用 - 您必须“执行”一个导入语句来检索模块 - Exec 是 eval 的“更强”形式,它支持语句,而 eval 仅用于表达式。

        【讨论】:

          猜你喜欢
          • 2011-03-16
          • 1970-01-01
          • 2023-04-01
          • 1970-01-01
          • 2020-03-13
          • 1970-01-01
          • 1970-01-01
          • 2017-04-27
          • 1970-01-01
          相关资源
          最近更新 更多