每个部分的 Python ConfigParser 唯一键
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/287757/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python's ConfigParser unique keys per section
提问by cdleary
I read the part of the docsand saw that the ConfigParser
returns a list of key/value pairs for the options within a section. I figured that keys did not need to be unique within a section, otherwise the parser would just return a mapping. I designed my config file schema around this assumption, then sadly realized that this is not the case:
我阅读了文档的一部分,看到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')]
Then I went back and found the part of the docs that I shouldhave read:
然后我回去找到了我应该阅读的文档部分:
Sections are normally stored in a builtin dictionary. An alternative dictionary type can be passed to the ConfigParser constructor. For example, if a dictionary type is passed that sorts its keys, the sections will be sorted on write-back, as will be the keys within each section.
部分通常存储在内置字典中。可以将替代字典类型传递给 ConfigParser 构造函数。例如,如果传递了对其键进行排序的字典类型,则这些部分将在回写时排序,每个部分中的键也是如此。
To keep my existing configuration file scheme (which I really like now ;) I'm thinking of passing a mapping-like object as mentioned above that accumulates values instead of clobbering them. Is there a simpler way to prevent key/value collapse that I'm missing? Instead of making a crazy adapter (that could break if ConfigParser
's implementation changes) should I just write a variant of the ConfigParser
itself?
为了保持我现有的配置文件方案(我现在真的很喜欢;)我正在考虑传递一个如上所述的类似映射的对象,该对象累积值而不是破坏它们。有没有更简单的方法来防止我遗漏的键/值崩溃?ConfigParser
我应该编写一个ConfigParser
自己的变体,而不是制作一个疯狂的适配器(如果的实现发生变化可能会中断)?
I feel like this may be one of those 'duh' moments where I'm only seeing the difficult solutions.
我觉得这可能是我只看到困难解决方案的那些“废话”时刻之一。
[Edit:]Here's a more precise example of how I'd like to use the same key multiple times:
[编辑:]这里有一个更精确的例子,说明我想多次使用同一个键:
[Ignored Paths]
ignore-extension: .swp
ignore-filename: tags
ignore-directory: bin
I dislike the comma-delimited-list syntax because it's hard on the eyes when you scale it to many values; for example, a comma delimited list of fifty extensions would not be particularly readable.
我不喜欢逗号分隔的列表语法,因为当你将它缩放到多个值时,它很难看;例如,以逗号分隔的 50 个扩展名列表就不是特别易读。
回答by Jeremy Cantrell
ConfigParser isn't designed to handle such conditions. Furthermore, your config file doesn't make sense to me.
ConfigParser 并非旨在处理此类情况。此外,您的配置文件对我来说没有意义。
ConfigParser gives you a dict-like structure for each section, so when you call parser.items(section), I'm expecting similar output to dict.items(), which is just a list of key/value tuples. I would never expect to see something like:
ConfigParser 为每个部分提供了一个类似于 dict 的结构,因此当您调用 parser.items(section) 时,我期待与 dict.items() 类似的输出,它只是一个键/值元组列表。我从没想过会看到类似的东西:
[('spam', 'eggs'), ('spam', 'ham')]
Not to mention, how would you expect the following to behave?:
更不用说,您如何期望以下行为?:
parser.get('Some Section', 'spam')
Which is the intended way to retrieve values.
这是检索值的预期方式。
If you want to store multiple values for the same key, I would suggest something like this in your config file:
如果你想为同一个键存储多个值,我会在你的配置文件中建议这样的东西:
[Some Section]
spam: eggs, ham
And this in your code:
这在您的代码中:
spam_values = [v.strip() for v in parser.get('Some Section', 'spam').split(',')]
Of course, this will only work for values that don't contain commas themselves or handle quoting. For that, you should employ a more advanced technique (see thisand this).
当然,这仅适用于本身不包含逗号或处理引用的值。为此,您应该采用更高级的技术(参见这个和这个)。
EDIT: If you don't mind the extra dependency, You could check out ConfigObj, which natively supports lists as a value type.
编辑:如果您不介意额外的依赖项,您可以查看ConfigObj,它本机支持列表作为值类型。
回答by anatoly techtonik
This deficiency of ConfigParser is the reason why pyglet used patched version of epydocto replace ConfigParser ini with this simple format:
ConfigParser 的这个缺陷就是为什么 pyglet 使用补丁版本的 epydoc来用这种简单的格式替换 ConfigParser ini的原因:
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
...
If you don't need sections - this approach can be useful.
如果您不需要部分 - 这种方法可能很有用。