动态调用配置文件中定义的Python类

4 投票
2 回答
2680 浏览
提问于 2025-04-17 06:10

我有一个配置文件 config.cfg,我用 Python 的 ConfigParser 模块来解析它。在其中一个部分,我想设置一些类似于 文件扩展名 : 类名 的配置。解析后得到的结果是一个字典:

types = {
  "extension1" : "ClassName1",
  "extension2" : "ClassName2"
}

编辑:我知道我现在可以这样做:

class_ = eval(types[extension])
foo = class()

但是我听说 eval 是个坏东西,不应该使用。

你知道有没有更好的方法来动态配置哪个文件扩展名对应哪个类吗?

2 个回答

0

如果module是包含名为classname的类的模块,你可以通过下面的方式获取这个类的对象:

class_ = getattr(module, classname)

(如果这个类在主模块中,可以使用import __main__来获取这个模块的模块对象。)

要在当前模块的全局范围内查找这个类,可以使用:

class_ = globals()[classname]

我觉得像Matt的回答中提到的静态字典是更好的解决方案。

7

你可以使用 eval,前提是配置文件里的类名和你Python代码里的类名完全一致(而且这些类在当前的作用域内!),但是…… eval 是个很危险的东西(这不是巧合,只有一字之差吧?我觉得不是!)


一个更安全的方法是添加一个额外的字典,用来将配置文件中的类名映射到Python代码中的类名。我建议这样做的原因有:

  • 配置文件不需要知道你代码里的名字
  • 可以在不改变代码的情况下修改配置文件,反之亦然
  • 避免使用 eval

所以它的样子可能是这样的:

mappingDict = {"ClassName1" : MyPythonClass1, 
               "ClassName2" : MyPythonClass2, ... }
# keys are strings, values are classes

然后你可以使用配置文件中的值进行查找:

myClassName = types['extension1']
myClass = mappingDict[myClassName]

撰写回答