Python的ConfigParser每个部分的唯一键 [英] Python's ConfigParser unique keys per section

查看:156
本文介绍了Python的ConfigParser每个部分的唯一键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了文档的一部分,并看到 ConfigParser 返回一个部分中选项的键/值对列表。我认为键不需要在一个部分中是唯一的,否则解析器将只返回一个映射。我设计了我的配置文件模式绕这个假设,然后悲伤地意识到不是这样的:

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

然后我回去,发现我应该阅读的文档的一部分:


部分通常存储在
内置字典中。另一个
字典类型可以传递给
ConfigParser构造函数。例如,
如果传递一个字典类型,
对其键进行排序,那么这些部分将以
的顺序排列,就像每个部分的
键一样。 / p>

保持我现有的配置文件方案(我现在真的很喜欢)我正在考虑传递一个类似映射的对象,如上所述以上这些积累了价值观,而不是扼杀他们。有没有一个更简单的方法来防止我失踪的键/值崩溃?而不是制作一个疯狂的适配器(如果 ConfigParser 的实现更改可能会破坏),我应该只写一个 ConfigParser 本身?



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



] 这是一个更为精确的例子,我将多次使用相同的密钥:

  [忽略的路径] 
ignore-extension:.swp
ignore-filename:tags
ignore-directory:bin

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

解决方案

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' / pre>

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



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


I read the part of the docs and 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:

>>> 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 should have 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.

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?

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.

解决方案

ConfigParser isn't designed to handle such conditions. Furthermore, your config file doesn't make sense to me.

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:

[('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 this and this).

EDIT: If you don't mind the extra dependency, You could check out ConfigObj, which natively supports lists as a value type.

这篇关于Python的ConfigParser每个部分的唯一键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆