如何使用Python文件中的数据初始化类
我想从一个简单的 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 个回答
你可以试试 self.__dict__.update(configFile.__dict__)
吗?我觉得这样应该没问题。
其实,有几种方法可以做到这一点。最简单的方法是使用 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,但在初始化变量时,两者几乎没有区别。