Les clés uniques de ConfigParser de Python par section

j'ai lu la partie de the docs et j'ai vu que le ConfigParser retourne une liste de combinaisons clé/valeur pour les options dans une section. J'ai pensé que les clés n'avaient pas besoin d'être uniques dans une section, sinon l'analyseur retournerait juste un mapping. J'ai conçu mon schéma de fichier de configuration autour de cette hypothèse, puis j'ai tristement réalisé que ce n'est pas le cas:

>>> 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')]

puis je suis retourné et ai trouvé la partie de la docs que je si avait lu:

Les Sections

sont normalement stockées dans un dictionnaire intégré. Alternative le type de dictionnaire peut être passé à ConfigParser constructor. Exemple, si un type de dictionnaire est passé que trie les clés, les sections seront trié sur write-back, Comme sera le touches dans chaque section.

pour garder mon schéma de fichier de configuration existant (que j'aime vraiment maintenant ;) je suis penser à passer un objet de type mapping comme mentionné ci-dessus qui accumule des valeurs au lieu de les écraser. Est-il un moyen plus simple de prévenir la clé/valeur effondrement que je suis absent? Au lieu de faire un adaptateur fou (qui pourrait se casser si l'implémentation de ConfigParser change), devrais-je simplement écrire une variante du ConfigParser lui-même?

j'ai l'impression que c'est peut-être un de ces moments 'duh' où je ne vois que les solutions difficiles.

[Edit:] voici un exemple plus précis de la façon dont je voudrais utiliser la même clé plusieurs fois:

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

Je n'aime pas la syntaxe de liste délimitée par des virgules parce que c'est dur pour les yeux quand vous la mettez à l'échelle à de nombreuses valeurs; par exemple, une liste délimitée par des virgules de cinquante extensions ne serait pas particulièrement lisible.

8
demandé sur cdleary 2008-11-13 21:20:11

2 réponses

ConfigParser n'est pas conçu pour gérer de telles conditions. En outre, votre fichier de configuration n'a pas de sens pour moi.

ConfigParser vous donne une structure de type dict pour chaque section, donc quand vous appelez parser.articles(l'article), j'attends de sortie similaire à la dict.items (), qui est juste une liste de tuples clé/valeur. Je ne m'attendais pas à voir quelque chose comme:

[('spam', 'eggs'), ('spam', 'ham')]

sans mentionner, comment vous attendez-vous à ce que les suivants se comportent?:

parser.get('Some Section', 'spam')

qui est le moyen prévu pour récupérer des valeurs.

Si vous voulez stocker plusieurs valeurs pour la même clé, je dirais quelque chose comme ceci dans votre fichier de configuration:

[Some Section]
spam: eggs, ham

et ceci dans votre code:

spam_values = [v.strip() for v in parser.get('Some Section', 'spam').split(',')]

bien sûr, cela ne fonctionnera que pour les valeurs qui ne contiennent pas de virgule elles-mêmes ou ne traitent pas de citation. Pour cela, vous devez utiliser une technique plus avancée (voir ce et ce ).

EDIT: si la dépendance supplémentaire ne vous dérange pas, vous pouvez vérifier ConfigObj , qui supporte nativement les listes comme un type de valeur.

11
répondu Jeremy Cantrell 2017-05-23 12:00:17

cette déficience de ConfigParser est la raison pour laquelle pyglet utilisé version corrigée d'epydoc pour remplacer ConfigParser ini avec ce format simple :

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

Si vous n'avez pas besoin de sections - cette approche peut être utile.

0
répondu anatoly techtonik 2012-11-12 08:51:04