2012-07-03 92 views
7

我在模板風格插值python中使用ConfigObj。通過**解包我的配置字典似乎沒有插值。這是一個功能還是錯誤?任何不錯的解決方法?爲什麼不用kwargs插入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' 

我期望第二行是/test/directory。爲什麼不插入** kwargs?

+0

的''**關鍵字參數僅解壓縮適用於映射。最有可能的是,'ConfigObj'實例沒有公開完整的[映射](http://docs.python.org/glossary.html#term-mapping)接口。 –

+0

ConfigObj *從dict繼承*,所以它肯定提供了完整的映射接口(事實上** unpack已*工作*它剛剛得到了錯誤的值)。我不確定「**」是如何得到數值的,但它明顯地繞過了插值,但我必須做一些實驗來解決。 – fuzzyman

+0

是不是有一些與直接從字典繼承有關的奇怪現象? ,http://stackoverflow.com/questions/3387691/python-how-to-perfectly-override-a-dict。我不是這方面的專家,但也許使用[MutableMapping](http://docs.python .org/library/collections.html#collections.MutableMapping)或[DictMixin](http://docs.python.org/library/userdict.html#UserDict.DictMixin)會更好嗎? –

回答

2

解壓縮關鍵字參數時,會創建一個新對象:類型爲dict。這本詞典包含配置的原始值(無插值)

示範:

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

要解決你的問題,你可以創建你的配置是這樣的擴展版本:

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

另一種更優雅的方式是簡單地避免開箱:這可以通過使用功能string.Formatter.vformat實現:

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

因爲我的ConfigObj在腳本過程中沒有改變,所以這樣會很好,但它確實看起來笨重! –

2

我有類似的問題。

解決方法是使用configobj的函數「.dict()」。這是可行的,因爲configobj返回一個真正的字典,Python知道如何解壓縮。

你舉的例子就變成:

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