2012-07-03 7 views
7

Ich verwende ConfigObj in Python mit Template-Stil-Interpolation. Wenn ich mein Konfigurationswörterbuch über ** entpacke, scheint es keine Interpolation zu geben. Ist das ein Feature oder ein Fehler? Irgendwelche netten Workarounds?Warum interpoliert ** kwargs nicht mit 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' 

würde ich die zweite Zeile erwarten /test/directory zu sein. Warum funktioniert Interpolation nicht mit ** kwargs?

+0

Das '' ** Stichwort Argument nur Auspacken für Zuordnungen funktioniert. Wahrscheinlich stellen 'ConfigObj'-Instanzen nicht die vollständige [mapping] (http://docs.python.org/glossary.html#term-mapping) Schnittstelle zur Verfügung. –

+0

ConfigObj * erbt * von dict, also bietet es definitiv die vollständige Mapping-Schnittstelle (und in der Tat hat das ** entpacken * funktioniert * es hat nur die falschen Werte). Ich bin mir nicht sicher, wie "**" Werte hervorbringt, aber es ist offensichtlich, dass die Interpolation umgangen wird. Ich muss etwas experimentieren, um das herauszufinden. – fuzzyman

+0

Gibt es nicht eine gewisse Seltsamkeit, wenn man direkt vom Diktat erbt? http://stackoverflow.com/questions/3387691/python-how-to-perfectly-override-a-dict Ich bin kein Experte in diesem Thema, aber vielleicht benutze ich das [MutableMapping] (http: //docs.python .org/library/collections.html # collections.MutableMapping) oder [DictMixin] (http://docs.python.org/library/userdict.html#UserDict.DictMixin) wäre besser? –

Antwort

2

Beim Entpacken des Schlüsselwortarguments wird ein neues Objekt erstellt: vom Typ dict. Das Wörterbuch enthält die die rohen Werte der Konfiguration (keine Interpolation)

Demonstration:

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

Ihr Problem zu beheben Sie könnten eine erweiterte Version Ihrer Konfiguration wie folgt erstellen:

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

Eine weitere elegantere Möglichkeit besteht darin, das Auspacken zu vermeiden: Dies kann durch Verwendung der Funktion string.Formatter.vformat:

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

Da mein ConfigObj nicht über den Verlauf des Skripts ändert, wird dies in Ordnung sein. Es scheint jedoch klobig! –

2

Ich hatte ein ähnliches Problem.

Eine Problemumgehung besteht darin, configobj-Funktion ".dict()" zu verwenden. Das funktioniert, weil configobj ein echtes Wörterbuch zurückgibt, das Python entpacken kann.

Ihr Beispiel wird:

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