2012-07-03 12 views
7

Sto usando ConfigObj in python con interpolazione in stile modello. Scompattare il mio dizionario di configurazione tramite ** non sembra fare interpolazione. È una caratteristica o un bug? Qualche soluzione alternativa?Perché non ** kwargs interpola con python ConfigObj?

$ cat my.conf 
foo = /test 
bar = $foo/directory 

>>> import configobj 
>>> config = configobj.ConfigObj('my.conf', interpolation='Template') 
>>> config['bar'] 
'/test/directory' 
>>> '{bar}'.format(**config) 
'$foo/directory' 

mi aspetto la seconda linea per essere /test/directory. Perché l'interpolazione non funziona con ** kwargs?

+0

Il '' argomento chiave ** disimballaggio funziona solo per le mappature. Molto probabilmente, le istanze di 'ConfigObj' non espongono l'intera interfaccia [mapping] (http://docs.python.org/glossary.html#term-mapping). –

+0

ConfigObj * eredita * da dict, quindi fornisce sicuramente l'interfaccia di mappatura completa (e infatti il ​​** unpack ha * funzionato * ha appena ottenuto i valori sbagliati). Non sono sicuro di come "**" "valuti i valori, è ovviamente bypassando l'interpolazione, dovrò fare qualche esperimento per risolvere il problema: – fuzzyman

+0

Non c'è qualche stranezza associata all'eredità diretta da dict? , http://stackoverflow.com/questions/3387691/python-how-to-perfectly-override-a-dict. Non sono esperto in questo, ma forse usando [MutableMapping] (http: //docs.python .org/library/collections.html # collections.MutableMapping) o [DictMixin] (http://docs.python.org/library/userdict.html#UserDict.DictMixin) sarebbe meglio? –

risposta

2

Quando si scompatta l'argomento parola chiave, viene creato un nuovo oggetto: di tipo dict. Questo dizionario contiene le le prime valori della configurazione (senza interpolazione)

Dimostrazione:

>>> id(config) 
31143152 
>>> def showKeywordArgs(**kwargs): 
...  print(kwargs, type(kwargs), id(kwargs)) 
... 
>>> showKeywordArgs(**config) 
({'foo': '/test', 'bar': '$foo/directory'}, <type 'dict'>, 35738944) 

Per risolvere il problema si potrebbe creare una versione espansa della vostra configurazione come questa:

>>> expandedConfig = {k: config[k] for k in config} 
>>> '{bar}'.format(**expandedConfig) 
'/test/directory' 

Un altro modo più elegante è quello di evitare semplicemente il disimballaggio: questo può essere ottenuto utilizzando la funzione string.Formatter.vformat:

import string 
fmt = string.Formatter() 
fmt.vformat("{bar}", None, config) 
+0

Dato che il mio ConfigObj non cambia nel corso dello script, questo andrà bene, ma sicuramente sembra clunky! –

2

Ho avuto un problema simile.

Una soluzione alternativa consiste nell'utilizzare la funzione di configobj ".dict()". Questo funziona perché configobj restituisce un vero dizionario, che Python sa come decomprimere.

Il vostro esempio diventa:

>>> import configobj 
>>> config = configobj.ConfigObj('my.conf', interpolation='Template') 
>>> config['bar'] 
'/test/directory' 
>>> '{bar}'.format(**config.dict()) 
'/test/directory' 
Problemi correlati