我有一个包含很长变量列表的类(至少有十几个)。在模块中,我首先导入一个常量文件,其中包含一些辅助方法和所有默认常量。
from myConstants import *
class SomeClass(ParentClass):
def __init__(var1=VAR1, ..., varN=VARN):
super(SomeClass, self).init(var1, ...)
self.varM = varM
问题:我希望能够在初始化文件时指定文件,其中文件包含myConstants.py
中常量的子集。不在init文件中的变量将从默认值加载。类似的东西:
sc = SomeClass(initFile='/path/to/file')
我的想法是有类似
的东西from myConstants import *
from ConfigParser import SafeConfigParser
class SomeClass(ParentClass):
def __init__(var1=VAR1, ..., varN=VARN, initFile=''):
if initFile:
parser = SafeConfigParser().read(initFile)
var1 = parser('constants', 'var1') if parser('constants', 'var1') else VAR1
var2 = parser('constants', 'var2') if parser('constants', 'var2') else VAR2
....
varN = parser('constants', 'varN') if parser('constants', 'varN') else VARN
else:
var1 = VAR1
...
varN = VARN
super(SomeClass, self).init(var1, ...)
self.varM = varM
问题:这是最好的方法吗?如果不是,那是什么?似乎有点长啰嗦。我也没有和ConfigParser结婚。
答案 0 :(得分:2)
我会使用两个单独的构造函数,一个接受一个文件,另一个接受显式参数。
class SomeClass(ParentClass):
@classmethod
def from_file(cls, init_file):
parser = SafeConfigParser()
parser.read(init_file)
var1 = parser.get('constants', 'var1') if parser.has_option('constants', 'var1') else VAR1
# likewise var2, ..., varN
# This results in a call to cls.__init__
return cls(var1, var2, ..., varN)
def __init__(var1=VAR1, ..., varN=VARN, initFile=''):
var1 = VAR1
...
varN = VARN
super(SomeClass, self).init(var1, ...)
self.varM = varM
x = SomeClass(1, 2, 3)
y = SomeClass.from_file(config_file)
答案 1 :(得分:0)
男人,这个ConfigParser清楚地显示了它的年龄 - 它应该有一个映射界面 - 我不得不戳一点 找到一种方法来获得它的价值 - 但这是更合适的 代码:
class SomeClass(ParentClass):
options = {"var1": VAR1, "var2": VAR2, ...}
def __init__( initFile='', **kwargs):
options = self.__class__.options.copy()
if initFile:
parser = SafeConfigParser().read(initFile)
for option_name in parser.options("constants"):
if options_name in options:
options[option_name] = parser.get("constants", option_name)
else:
for key, value in kwargs:
if key in options:
options[key] = value
super(SomeClass, self).init(**options)
self.varM = varM
答案 2 :(得分:0)
您可以尝试使用configparser对象并使用默认值字典对其进行修改以满足您的需求:
default_values = {
"var1": "42",
"var2": "23",
}
conf_parser = configparser.ConfigParser()
conf_parser.read(config_file)
for var, default_value in default_values.keys():
if v not in conf_parser["DEFAULT"]:
conf_parser["DEFAULT"][var] = default_value
这应该覆盖configparser中的所有缺失值。
之后,您可以传递configparser对象并使用config_parser["DEFAULT"]["var1"]
访问所有变量,依此类推。这样做的好处是所有变量都整齐地捆绑在一起,而构造函数只有一个参数。
另一方面,这有点难看,配置解析器只知道如何使用字符串,所以字典可能更适合这个任务。
我希望这会有所帮助。