ConfigObj与单元素列表
我在研究ConfigObj的时候,遇到了一个关于验证和单元素列表的问题。假设我有一个配置规范,长得像这样:
config_specification = """[Data]
[[__many__]]
type = option('sense.xml')
transport = string
sensors = list
[[[Identifier]]]
type = option("name", "mac", "uuid")
adapter = string(default='')
name = string(default='')
file = string(default='')"""
这个列表其实可以只有一个元素,也可以有多个元素。我可以很简单地添加多个元素:
[Data]
[[primary]]
type = sense.xml
transport = $http
sensors = $virtual, $gpio, $adc
[[[Identifier]]]
type = name
name = VirtualRelay01
但是,下面这个是无效的。它不会把它转换成一个包含1个元素的列表:
sensors = $virtual
我尝试了几种不同的写法。这种写法不行:
sensors = {$virtual}
这个也不行:
sensors = [$virtual]
如果我这样做,它却给我返回了一个包含两个元素的列表!其中一个是空字符串:
sensors = ($virtual,)
我有好几个这样的部分,并且我把它们放在一个循环里。我把它们应用到只接受列表的类上,我不想一个个地写代码来处理这些特殊情况(更不用说,这样会导致验证失败)。
为了完整起见,这里是我如何进行验证的:
cfg = ConfigObj(filename, configspec=config_specification.split('\n'))
test = cfg.validate(Validator())
valid = True
for (section_list, key, _) in flatten_errors(cfg, test):
if key is not None:
print('Invalid value for key {0} in section {1}'.format(key,', '.join(section_list)))
valid = False
else:
print('Section {0} failed validation'.format(', '.join(section_list)))
valid = False
if not valid:
exit(3)