Уникальные ключи Python ConfigParser для каждого раздела - PullRequest
8 голосов
/ 13 ноября 2008

Я прочитал часть документов и увидел, что 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?

Я чувствую, что это может быть один из тех "скучных" моментов, когда я вижу только сложные решения.

[Edit:] Вот более точный пример того, как я хотел бы использовать один и тот же ключ несколько раз:

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

Мне не нравится синтаксис с разделителями-запятыми, потому что это трудно на глаза, когда вы масштабируете его до многих значений; например, список из пятидесяти расширений, разделенных запятыми, не будет особенно удобочитаемым.

Ответы [ 2 ]

11 голосов
/ 13 ноября 2008

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 , который изначально поддерживает списки в качестве типа значения.

0 голосов
/ 12 ноября 2012

Этот недостаток ConfigParser является причиной, по которой pyglet использовал исправленную версию epydoc для замены ini ConfigParser на этот простой формат :

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

Если вам не нужны разделы - этот подход может быть полезен.

...