如何使用Python文件中的数据初始化类

5 投票
2 回答
5716 浏览
提问于 2025-04-16 16:56

我想从一个简单的 Python 文件中初始化一个类,这个文件是在调用脚本时指定的。这个配置文件叫做 myconfig.py,内容是:

str='home'
val=2
flt=7.0

我想在类初始化的时候这样调用它。我的一个目标是也在这个文件中定义变量的类型。我知道有 configparser 这个工具,但如果能让这个方法工作的话,它会更简洁。

class ClassInit(object):
    def __init__(self, configFile):
        fp, path, des = imp.find_module('',configFile)
        imp.load_module(configFile, fp, path, des)
        self.__dict__ = configFile.__dict__
        fp.close()

    def printVal(self):
        print '%s %0.2f'%(self.str, self.val)

if __name__ == '__main__':
    srcDir = 'src/'
    config = osp.join(srcDir, argv[0]) # config for current run 
    ci = ClassInit(config)
    ci.printVal()

这样的事情可能吗?

2 个回答

0

你可以试试 self.__dict__.update(configFile.__dict__) 吗?我觉得这样应该没问题。

2

其实,有几种方法可以做到这一点。最简单的方法是使用 eval()exec 来在类的范围内执行这段代码。但这也是最危险的方法,特别是当这些文件可能是别人创建的时候。在这种情况下,文件的创建者可以写一些恶意代码,几乎可以做任何事情。你可以覆盖全局字典中的 __builtins__ 键,但我不确定这样做是否能让 eval/exec 完全安全。例如:

class ClassInit(object):
    def __init__(self, configFile):
        f = open(configFile)
        config = f.read()
        f.close()
        config_dic = { '__builtins__': None}
        exec 'a = 4' in config_dic
        for key, value in config_dic.iteritems():
            if key != '__builtins__':
                setattr(self, key, value)

这种方法会杀掉不安全的 'builtins' 对象,但仍然不是很安全。比如,文件可能会定义一个函数,用恶意代码覆盖你类中的某个函数。所以我真的不推荐这种方法,除非你完全控制那些 .py 文件。

一种更安全但更复杂的方法是创建一个自定义解释器,来解释这个文件,但不允许运行任何自定义代码。

你可以查看以下讨论,看看一些关于解析库或其他更安全的 eval() 替代方案的建议: Python: make eval safe

此外,如果你只需要 config.py 文件来以一种好的方式初始化一些变量,而不需要从里面调用复杂的 Python 函数,那么你可以考虑使用 JSON。Python 2.6 及以上版本包含 simplejson,你可以用它从文件初始化一个对象。语法是 JavaScript 而不是 Python,但在初始化变量时,两者几乎没有区别。

撰写回答