2009-11-20 22 views
41

Come posso convertire il risultato di un ConfigParser.items (sezione '') per un dizionario per formattare una stringa del tipo qui:Convertire ConfigParser.items ('') al dizionario

import ConfigParser 

config = ConfigParser.ConfigParser() 
config.read('conf.ini') 

connection_string = ("dbname='%(dbname)s' user='%(dbuser)s' host='%(host)s' " 
        "password='%(password)s' port='%(port)s'") 

print connection_string % config.items('db') 
+4

Attenzione a usare _sections: questa variabile non è documentata, quindi non è garantito il funzionamento nelle future versioni di Python – Bertera

+1

Questo è valido per python 2, ma se stai usando python 3 puoi semplicemente decomprimere la configurazione con subscript in formato(). "your {pattern}". Format (** config ['db']) – Hovis

risposta

47

Questo è già stato fatto per voi in config._sections. Esempio:

$ cat test.ini 
[First Section] 
var = value 
key = item 

[Second Section] 
othervar = othervalue 
otherkey = otheritem 

E poi:

>>> from ConfigParser import ConfigParser 
>>> config = ConfigParser() 
>>> config.read('test.ini') 
>>> config._sections 
{'First Section': {'var': 'value', '__name__': 'First Section', 'key': 'item'}, 'Second Section': {'__name__': 'Second Section', 'otherkey': 'otheritem', 'othervar': 'othervalue'}} 
>>> config._sections['First Section'] 
{'var': 'value', '__name__': 'First Section', 'key': 'item'} 

Edit: La mia soluzione per lo stesso problema è stato downvoted quindi dovrò ulteriormente illustrare come la mia risposta fa la stessa cosa, senza dover passare alla sezione attraverso dict(), perché config._sections è fornito dal modulo per voi già.

Esempio Test.ini:

[db] 
dbname = testdb 
dbuser = test_user 
host = localhost 
password = abc123 
port = 3306 

magia accada:

>>> config.read('test.ini') 
['test.ini'] 
>>> config._sections 
{'db': {'dbname': 'testdb', 'host': 'localhost', 'dbuser': 'test_user', '__name__': 'db', 'password': 'abc123', 'port': '3306'}} 
>>> connection_string = "dbname='%(dbname)s' user='%(dbuser)s' host='%(host)s' password='%(password)s' port='%(port)s'" 
>>> connection_string % config._sections['db'] 
"dbname='testdb' user='test_user' host='localhost' password='abc123' port='3306'" 

Quindi questa soluzione è non sbagliato, e richiede in realtà uno di meno passo. Grazie per esserti fermato!

+0

Questo è un modo sbagliato, poiché non tiene conto dei valori predefiniti e le variabili non sono interpolate. –

+1

Com'è questa "via sbagliata" se dà lo stesso risultato? – jathanism

+2

Non sto dicendo che è sbagliato, ma non posso usarlo, perché l'ho provato con il% di sostituzione del sintetizzatore di configurazione integrato (sintassi). Per l'inconsapevole questo permette l'uso dei valori di configurazione in altri valori di configurazione. Questi non sono espansi nel membro _sections, ma sono tramite la funzione items(). – AlwaysTraining

76

Hai provato

print connection_string % dict(config.items('db')) 

?

+5

Questa dovrebbe essere la risposta accettata. – johnharris85

+0

destra. questo ha funzionato per me, mentre quello approvato in qualche modo no .. forse è una cosa in versione Python .. –

+5

@Ricky, suppongo che l'utente non debba accedere a _sections. – Dacav

10

So che questo è stato chiesto molto tempo fa e una soluzione scelta, ma la soluzione selezionata non tiene conto dei valori predefiniti e della sostituzione delle variabili. Dato che è il primo colpo quando si cerca la creazione di dts da parser, ho pensato di pubblicare la mia soluzione che include le sostituzioni predefinite e variabili usando ConfigParser.items().

from ConfigParser import SafeConfigParser 
defaults = {'kone': 'oneval', 'ktwo': 'twoval'} 
parser = SafeConfigParser(defaults=defaults) 
parser.set('section1', 'kone', 'new-val-one') 
parser.add_section('section1') 
parser.set('section1', 'kone', 'new-val-one') 
parser.get('section1', 'ktwo') 
parser.add_section('section2') 
parser.get('section2', 'kone') 
parser.set('section2', 'kthree', 'threeval') 
parser.items('section2') 
thedict = {} 
for section in parser.sections(): 
    thedict[section] = {} 
    for key, val in parser.items(section): 
     thedict[section][key] = val 
thedict 
{'section2': {'ktwo': 'twoval', 'kthree': 'threeval', 'kone': 'oneval'}, 'section1': {'ktwo': 'twoval', 'kone': 'new-val-one'}} 

Una funzione comoda per fare questo potrebbe essere simile:

def as_dict(config): 
    """ 
    Converts a ConfigParser object into a dictionary. 

    The resulting dictionary has sections as keys which point to a dict of the 
    sections options as key => value pairs. 
    """ 
    the_dict = {} 
    for section in config.sections(): 
     the_dict[section] = {} 
     for key, val in config.items(section): 
      the_dict[section][key] = val 
    return the_dict 
2

Per una singola sezione, ad esempio, "generale", puoi fare:

dict(parser['general']) 
+0

(Mi dispiace per prima, commento cancellato! Ho totalmente misparso la tua risposta.) – sage

20

Come ho fatto in una sola riga.

my_config_parser_dict = {s:dict(config.items(s)) for s in config.sections()} 

Non più di altre risposte, ma quando non è il vero business del vostro metodo e avete bisogno in un solo posto usare meno linee e prendere il potere di compressione dict potrebbe essere utile.