如何使用ConfigParser提取未知数量的值对?

时间:2015-05-20 19:41:06

标签: python ini configparser

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实际上会发生的最新项目(或者是最早的项目?)会覆盖其他项目......如果[]甚至被接受为配置密钥。

是否有任何既定的最佳实践在配置文件中表达这样的内容?

1 个答案:

答案 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}]