动态调用配置文件中定义的Python类
我有一个配置文件 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]