9

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.

4

2 に答える 2

10

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をチェックしてください。

于 2008-11-13T19:24:23.890 に答える
0

この 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
...

セクションが必要ない場合は、このアプローチが役立ちます。

于 2012-11-12T08:51:04.050 に答える