2010-07-10 4 views
17

Normalmente, codice come segue per ottenere un particolare elemento in una variabile come segueLeggi tutto il contenuto nel file ini nel dizionario con Python

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 

C'è un modo di leggere tutti i contenuti in un dizionario Python ?

Per esempio

 
[A] 
x=1 
y=2 
z=3 
[B] 
x=1 
y=2 
z=3 

è scritto in

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

risposta

26

Suggerisco sottoclassi ConfigParser.ConfigParser (o SafeConfigParser, & c) per accedere in modo sicuro il "protetto" attributi (nomi che iniziano con il singolo trattino - "privato" sarebbero nomi che iniziano con due sottolineatura, per non essere accessibile anche in sottoclassi ...):

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 

Questo emula la solita logica del parser di configurazione, ed è garantito il funzionamento in tutte le versioni di Python dove c'è un modulo ConfigParser.py (fino a 2.7, che è l'ultimo della serie 2.* - sapendo che non ci sarà nessun futuro Python 2. Ogni versione è come compati la possibilità può essere garantita ;-).

Se è necessario supportare le future versioni Python 3.* (fino a 3.1 e probabilmente il più presto prossima 3.2 Va bene, basta rinominare il modulo per tutto minuscolo configparser invece ovviamente) potrebbe essere necessario un po 'di attenzione/tweaks alcuni anni lungo la strada, ma non mi aspetterei nulla di importante.

23

sono riuscito ad ottenere una risposta, ma mi aspetto che ci dovrebbe essere uno migliore.

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

Penso che questa sia una soluzione molto buona, perché non sei felice con lui? –

+2

Questa dovrebbe essere la risposta perché risolve il problema senza dover utilizzare l'attributo "_sections" "privato". E, naturalmente, se si ha bisogno di usare un OrderedDict, basta usarlo al posto del comando regolare. – SizzlingVortex

+1

Sostituire 'dizionario' con un' defaultdict (dict) 'rimuoverà la creazione di dettatura intermedia. – noxdafox

10

I dati di istanza per ConfigParser sono memorizzati internamente come dict annidato. Invece di ricrearlo, potresti semplicemente copiarlo.

>>> 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'}} 

Edit: di

Alex Martelli solution è più pulita, più robusto e più bella. Mentre questa era la risposta accettata, suggerirei invece di usare il suo approccio. Vedi il suo commento a questa soluzione per maggiori informazioni.

+4

Sono sempre riluttante ad accedere ai nomi protetti degli attributi ("start-with-underscore") (e l'assurda complicazione di passare attraverso '__dict__' non aiuta affatto -' d = p._sections.copy() 'è esattamente equivalente, più semplice e più diretto). Questo è il motivo per cui ho suggerito nella mia risposta l'alternativa all'uso di una sottoclasse; le sottoclassi sono _atteso_ per accedere agli attributi protetti della classe base. In C++ questo è applicato; in Python, non lo è, ma è perché gli utenti dovrebbero essere disciplinati abbastanza da non _need_ enforcement ;-). –

1

Come analizzare il file ini in py?

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

dove file Test.ini contiene:

[DEFAULT] 
network=shutup 
others=talk 
6

so che questa domanda è stato chiesto 5 anni fa, ma oggi ho fatto questo dict comprensione thingy:

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

Un'altra cosa da considerare è che, ConfigParser converte i valori chiave in lettere minuscole, quindi nel caso in cui si convertano le voci di configurazione in un dizionario incrociare i requisiti. Ho dovuto affrontare un problema a causa di questo. Per me stavo avendo le chiavi Camel-Case quindi, ho dovuto cambiare una certa quantità di codice quando ho iniziato ad usare il dizionario invece dei file.Il metodo ConfigParser.get() converte internamente la chiave in lettere minuscole.

-1

da https://wiki.python.org/moin/ConfigParserExamples

def ConfigSectionMap(section): 
dict1 = {} 
options = Config.options(section) 
for option in options: 
    try: 
     dict1[option] = Config.get(section, option) 
     if dict1[option] == -1: 
      DebugPrint("skip: %s" % option) 
    except: 
     print("exception on %s!" % option) 
     dict1[option] = None 
return dict1