2012-07-03 24 views
7

Şablon stili enterpolasyonlu python'da ConfigObj kullanıyorum. Yapılandırma sözlüğümün ** üzerinden kaldırılması enterpolasyon yapmıyor gibi görünüyor. Bu bir özellik mi yoksa bir böcek mi? Güzel bir çözüm var mı?Neden kwargs python ConfigObj ile interpolasyon yapmıyor?

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

Ben ikinci hat /test/directory olmasını beklersiniz. Neden enterpolasyon ** kwargs ile çalışmıyor?

+0

'**' anahtar kelime bağımsız değişken yalnızca açma eşleştirmeleri için çalışır. Muhtemelen 'ConfigObj' örnekleri tam [haritalama] (http://docs.python.org/glossary.html#term-mapping) arayüzünü göstermiyor. –

+0

ConfigObj * dict'dan * devralır, bu yüzden tam olarak eşleme arayüzünü sağlar (ve ** unpack'in * çalıştığı * işe yaramıştır * sadece yanlış değerlere sahiptir). "**" "değerlerin nasıl çıkacağından emin değilim, açıkçası enterpolasyonu atlatıyor. Çalışmak için biraz deneme yapmak zorunda kalacağım. – fuzzyman

+0

Doğrudan dict'ten miras kalan bir tuhaflık yok mu? http://stackoverflow.com/questions/3387691/python-how-to-perfectly-override-a-dict Ben bu konuda uzman değilim, ama belki de [MutableMapping] kullanarak (http: //docs.python .org/library/collections.html # collections.MutableMapping) veya [DictMixin] (http://docs.python.org/library/userdict.html#UserDict.DictMixin) daha iyi olurdu? –

cevap

2

Anahtar kelime bağımsız değişkenini paketinden çıkarırken, yeni bir nesne oluşturulur: dict. Bu sözlük (hayır enterpolasyon) yapılandırmanın ham değerleri içeren

Gösteri:

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

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

sorununuzu gidermek için bu gibi bir şekle sahip genişlemiş sürümünü oluşturabilir

Başka bir daha zarif yol, basit bir şekilde paketlemekten kaçınmaktır: Bu, string.Formatter.vformat:

import string 
fmt = string.Formatter() 
fmt.vformat("{bar}", None, config) 
işlevi kullanılarak gerçekleştirilebilir.
+0

Benim ConfigObj benim betik boyunca değişmez beri, bu iyi olacak. –

2

Benzer bir sorunla karşılaştım.

Bir geçici çözüm, configobj işlevinin ".dict()" işlevini kullanmaktır. Bu, configobj, Python'un nasıl açılacağını bildiği gerçek bir sözlük döndürdüğü için çalışır.

Sizin örnek olur:

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