在this question中,OP希望使用ConfigParser从配置文件中提取未知数量的部分,其中所有部分共享相同的内部格式。
在我的情况下,我限制将所有内容限制在一个部分。我试图找出一种可维护的,理智的存储方式"对"数据的。一个人为的例子可以更好地解释事情:
[pings]
host1 = foo.com
port1 = 80
interval1 = 60
host2 = bar.com
port2 = 8080
interval2 = 300
host3 = baz.com
port3 = 443
interval3 = 15
这可以在递增索引循环中读取,一旦我们到达未找到期望值的迭代,我们可以推测我们已经到达数据的末尾并停止。问题是这是丑陋且不可维护的,更糟糕的是,假设我们想要注释host1
...我们必须重新编号列表中的其他所有内容以防止扫描提前终止。
这并没有让我觉得好多了:
[pings]
hosts = foo.com, bar.com, baz.com
ports = 80, 8080, 443
intervals = 60, 300, 15
很难阅读任何大量的项目,易于编辑等等。
我可以转动它:
[pings]
ping1 = foo.com, 80, 60
ping2 = bar.com, 8080, 300
ping3 = baz.com, 443, 15
有点逻辑分组,但如果添加/删除/重新排列项目,仍会遇到行重新编号问题。此外,它很容易迷失(想象一下,扫描一张非常宽的CSV表格)。
我想避免嵌入JSON或任何形式的正式对象文字表示法。编辑错误的机会太多,无法解析解析器。
很久以前我记得使用PHP,你可以添加可变数量的查询字符串项,如?host[]=foo.com&host[]=bar.com&host[]=baz.com
,$_GET['host']
全局将成为一个包含三个项目的数组。窃取这种语法,我可以这样做:
[pings]
host[] = foo.com
port[] = 80
interval[] = 60
host[] = bar.com
port[] = 8080
interval[] = 300
host[] = baz.com
port[] = 443
interval[] = 15
......或:
[pings]
ping[] = foo.com, 80, 60
ping[] = bar.com, 8080, 300
ping[] = baz.com, 443, 15
...添加/删除项目时会有一点担心。但我相信ConfigParser实际上会发生的最新项目(或者是最早的项目?)会覆盖其他项目......如果[]
甚至被接受为配置密钥。
是否有任何既定的最佳实践在配置文件中表达这样的内容?
答案 0 :(得分:0)
如果没有测试,我会写一些类似的东西:
config = ConfigParser.ConfigParser()
with open('path/to/file.ini') as config_f:
config.readfp(config_f)
# config.readfile in 3.2+
configitems = config.section('pings')
ping_infos = [{'host':host, 'port':port, 'interval':interval} for
host, port, interval in [value.split()]} for
key,value in configitems if key.startswith('ping')]
然后您可以将配置文件写为
[pings]
; pingANYUNIQUECHAR = hostname, portnumber, interval
ping-foo.com = foo.com, 80, 60
ping-bar.com = bar.com, 8080, 300
你最终会得到:
ping_infos = [{'host': 'foo.com',
'port': '80',
'interval': 60},
{'host': 'bar.com',
'port': 8080,
'interval': 300}]