我阅读了the docs的部分,看到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
的实现发生变化可能会中断)?
我觉得这可能是我只看到困难解决方案的那些“呃”时刻之一。
[编辑:] 以下是我多次使用相同密钥的更精确示例:
[Ignored Paths]
ignore-extension: .swp
ignore-filename: tags
ignore-directory: bin
我不喜欢逗号分隔列表语法,因为当你将它缩放到很多值时,它的眼睛很难看;例如,以逗号分隔的50个扩展名列表不会特别易读。
答案 0 :(得分:11)
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(',')]
当然,这只适用于不包含逗号本身或处理引用的值。为此,您应该采用更先进的技术(请参阅this和this)。
编辑:如果你不介意额外的依赖,你可以查看ConfigObj,它本身支持列表作为值类型。
答案 1 :(得分:0)
ConfigParser的这个缺陷是pyglet使用patched version of epydoc替换ConfigParser ini的原因simple format:
name: pyglet
url: http://www.pyglet.org/
output: html
target: doc/api/
...
module: pyglet
exclude: pyglet.gl.gl
exclude: pyglet.gl.agl
exclude: pyglet.gl.lib_agl
exclude: pyglet.gl.wgl
...
如果您不需要部分 - 这种方法很有用。