一尘不染

Python 的 ConfigParser 每个部分的唯一键

python

我阅读了文档的一部分,发现它ConfigParser返回了一个部分中选项的键/值对列表。我认为键在一个部分中不需要是唯一的,否则解析器只会返回一个映射。我围绕这个假设设计了我的配置文件架构,然后遗憾地意识到事实并非如此:

>>> from ConfigParser import ConfigParser
>>> from StringIO import StringIO
>>> fh = StringIO("""
... [Some Section]
... spam: eggs
... spam: ham
... """)
>>> parser = ConfigParser()
>>> parser.readfp(fh)
>>> print parser.items('Some Section')
[('spam', 'ham')]

然后我回去找到了我应该阅读的文档部分:

部分通常存储在内置字典中。可以将替代字典类型传递给 ConfigParser 构造函数。例如,如果传递了对其键进行排序的字典类型,则这些部分将在回写时进行排序,每个部分中的键也是如此。

为了保留我现有的配置文件方案(我现在真的很喜欢;),我正在考虑传递一个如上所述的类似映射的对象,它会累积值而不是破坏它们。有没有更简单的方法来防止我缺少的键/值崩溃?而不是制作一个疯狂的适配器(如果ConfigParser实现更改可能会破坏)我应该只编写ConfigParser它本身的变体吗?

我觉得这可能是我只看到困难解决方案的那些“duh”时刻之一。

[编辑:]这是一个更精确的示例,说明我想如何多次使用同一个键:

[Ignored Paths]
ignore-extension: .swp
ignore-filename: tags
ignore-directory: bin

我不喜欢逗号分隔列表语法,因为当您将其缩放到多个值时,它很难看;例如,五十个扩展名的逗号分隔列表将不是特别可读。


阅读 129

收藏
2022-06-14

共1个答案

一尘不染

ConfigParser 并非旨在处理此类情况。此外,您的配置文件对我没有意义。

ConfigParser 为每个部分提供了一个类似 dict 的结构,因此当您调用 parser.items(section) 时,我期待与 dict.items() 类似的输出,它只是键/值元组的列表。我从没想过会看到类似的东西:

[('spam', 'eggs'), ('spam', 'ham')]

更不用说,您希望以下行为如何?:

parser.get('Some Section', 'spam')

这是检索值的预期方式。

如果你想为同一个键存储多个值,我会在你的配置文件中建议这样的东西:

[Some Section]
spam: eggs, ham

这在你的代码中:

spam_values = [v.strip() for v in parser.get('Some Section', 'spam').split(',')]

当然,这仅适用于本身不包含逗号或处理引号的值。为此,您应该采用更先进的技术。

编辑:如果您不介意额外的依赖,您可以查看ConfigObj,它本机支持列表作为值类型。

2022-06-14