我有一个配置模块projectConfig
,用于解析项目的样本表:
class SampleSheetFields():
FIELD_1 = "field1"
FIELD_2 = "field2"
class SampleSheetFieldsOld():
FIELD_1 = "field_1"
FIELD_2 = "field_2"
我一直在使用其他模块中的第一个类:
from projectConfig import SampleSheetFields as ssFields
class SomeClass
def __init__(self):
...
check(someContent, ssFields.FIELD_1)
事情是我使用ssFields
的引用开发了我的软件。在某些时候,新的规范说软件也应该使用具有不同字段名称的样本表。我发现实现这一目标的最快方式是在SampleSheetFieldsOld
中添加类projectConfig
并在我的模块中进行条件导入:
class SomeClass:
def __init__(self, useOld):
if useOld:
from projectConfig import SampleSheetFieldsOld as ssFields
else:
from projectConfig import SampleSheetFields as ssFields
...
check(someContent, ssFields.FIELD_1)
请注意,使用的必填字段具有相同的名称,因此没有冲突或缺少字段。该计划按预期运作。
我的问题是:
答案 0 :(得分:3)
这可能不是最糟糕的事情,但我发现的问题是你现在已经锁定了两个配置选项,无论是新旧配置。如果你有一天需要添加第三个或第四个等等怎么办?你再也不能使用简单的布尔测试了。
此外,您的配置选项看起来都只是简单的字符串值,可通过字符串键访问。你不需要上课。
我的建议是忘记使用源代码进行配置并使用配置文件。在projectConfig
中,您可以从文件初始化dict
,其路径/名称可以在命令行上提供,也可以以任何方便的方式提供。所以projectConfig.py
可能是这样的:
config_options = {}
def load_configuration(filename):
with open(filename) as f:
for line in f:
# get key and value
config_options[key] = value
然后,无论您需要获取字段名称,只需访问projectConfig.config_options['field_key']
,例如
from projectConfig import config_options
class SomeClass
def __init__(self):
...
check(someContent, config_options['FIELD_1'])
如果有合理的默认值,请使用dict.get(key, default)
。这样,每次需要切换到一组不同的字段名称时,您只需创建一个新的配置文件,而不必触摸代码。
Python的标准库包含configparser
module,可以为您处理加载。
答案 1 :(得分:0)
如果您只需要类属性,则可以使用type
创建一个类工厂来创建新类,例如:
FIELDS = dict(
new=dict(FIELD_1="field1", FIELD_2="field2"),
old=dict(FIELD_1="field_1", FIELD_2="field_2"),
}
def sample_sheet_field_factory(field_spec='new'):
return type("SampleSheetFields", (object,), FIELDS[field_spec])
这可以很容易地扩展到更多的字段规范集,并且不需要条件导入:
from wherever import sample_sheet_field_factory
class SomeClass(object):
def __init__(self, use_old):
ss_fields = sample_sheet_field_factory("old" if use_old else "new")
check(some_content, ss_fields.FIELD_1)
你也可以使用namedtuple
,而不是一个类,它会更轻一些。请注意编辑符合the style guide。