web-dev-qa-db-fra.com

Lire tout le contenu du fichier ini dans le dictionnaire avec Python

Normalement, je code comme suit pour obtenir un élément particulier dans une variable comme suit

try:
    config = ConfigParser.ConfigParser()
    config.read(self.iniPathName)
except ConfigParser.MissingSectionHeaderError, e:
    raise WrongIniFormatError(`e`)

try:
    self.makeDB = config.get("DB","makeDB")
except ConfigParser.NoOptionError:
    self.makeDB = 0

Est-il possible de lire tout le contenu d'un dictionnaire python?

Par exemple

 [A] 
 X = 1 
 Y = 2 
 Z = 3 
 [B] 
 X = 1 
 y = 2 
 z = 3 

est écrit dans

 val ["A"] ["x"] = 1 
 ... 
 val ["B"] ["z"] = 3 
18
prosseek

Je suggère de sous-classer ConfigParser.ConfigParser (ou SafeConfigParser, & c) pour accéder en toute sécurité aux attributs "protected" (les noms commençant par un trait de soulignement simple - "privé" seraient des noms commençant par deux underscores, qui ne seraient pas accessibles même dans les sous-classes. .):

import ConfigParser

class MyParser(ConfigParser.ConfigParser):

    def as_dict(self):
        d = dict(self._sections)
        for k in d:
            d[k] = dict(self._defaults, **d[k])
            d[k].pop('__name__', None)
        return d

Cela reproduit la logique habituelle des analyseurs de configuration et fonctionne dans toutes les versions de Python comportant un module ConfigParser.py (jusqu'à la version 2.7, dernier élément de la série 2.*, sachant qu'il n'y aura pas de futur Python 2.any versions est comment la compatibilité peut être garantie ;-).

Si vous devez prendre en charge les versions futures de 3.* Python (jusqu’à la version 3.1 et probablement la version 3.2 à venir, cela devrait aller, il suffit de renommer le module en version tout en minuscule configparser au lieu bien sûr), cela nécessitera peut-être une attention/quelques ajustements dans quelques années. , mais je n’attendrais rien de majeur.

30
Alex Martelli

J'ai réussi à obtenir une réponse, mais je pense qu'il devrait y en avoir une meilleure.

dictionary = {}
for section in config.sections():
    dictionary[section] = {}
    for option in config.options(section):
        dictionary[section][option] = config.get(section, option)
24
prosseek

Les données d'instance de ConfigParser sont stockées en interne sous forme de dict imbriqué. Au lieu de le recréer, vous pouvez simplement le copier.

>>> import ConfigParser
>>> p = ConfigParser.ConfigParser()
>>> p.read("sample_config.ini")
['sample_config.ini']
>>> p.__dict__
{'_defaults': {}, '_sections': {'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B':         {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}}, '_dict': <type 'dict'>}
>>> d = p.__dict__['_sections'].copy()
>>> d
{'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B': {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}}

Modifier:

La solution d'Alex Martelli est plus propre, plus robuste et plus jolie. Bien que ce soit la réponse acceptée, je suggérerais d’utiliser plutôt son approche. Voir son commentaire sur cette solution pour plus d'informations.

10
Andrew

Je sais que cette question a été posée il y a 5 ans, mais aujourd'hui j'ai fait ce truc de compréhension de dict:

parser = ConfigParser()
parser.read(filename)
confdict = {section: dict(parser.items(section)) for section in parser.sections()}
6
Evgeny Sharypin

Comment analyser le fichier ini dans un py?

import ConfigParser
config = ConfigParser.ConfigParser()
config.read('/var/tmp/test.ini')
print config.get('DEFAULT', 'network')

Où le fichier test.ini contient:

[DEFAULT]
network=shutup
others=talk
1
YumYumYum

Une dernière chose à faire est que ConfigParser convertit les valeurs de clé en minuscules, par conséquent, au cas où vous convertissez les entrées de configuration en dictionnaire, vérifiez vos exigences. J'ai fait face à un problème à cause de cela. Pour moi, j'avais des clés de casier à chameaux, j'ai donc dû changer une partie du code lorsque j'ai commencé à utiliser le dictionnaire au lieu de fichiers. La méthode ConfigParser.get() convertit en interne la clé en minuscule.

0
avitash