2012-07-03 7 views
7

Estoy usando ConfigObj en python con interpolación de estilo de plantilla. Desenredar mi diccionario de configuración a través de ** no parece hacer interpolación. ¿Es esta una característica o un error? ¿Alguna buena solución?¿Por qué ** kwargs no 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' 

yo esperaría que la segunda línea para ser /test/directory. ¿Por qué la interpolación no funciona con ** kwargs?

+0

El '' ** argumento de palabra clave desembalaje sólo funciona para las asignaciones. Lo más probable es que las instancias 'ConfigObj' no expongan la interfaz completa [mapeo] (http://docs.python.org/glossary.html#term-mapping). –

+0

ConfigObj * hereda * de dict, por lo que definitivamente proporciona la interfaz de mapeo completa (y de hecho el ** desempaquetar * ha funcionado * acaba de obtener los valores incorrectos). No estoy seguro de cómo "**" "obtiene los valores, sin embargo, obviamente se está pasando por alto la interpolación. Tendré que hacer algunos experimentos para resolver. – fuzzyman

+0

¿No hay alguna rareza asociada con heredar directamente de dict? , http://stackoverflow.com/questions/3387691/python-how-to-perfectly-override-a-dict. No soy un experto en esto, pero quizás usando el [MutableMapping] (http: //docs.python .org/library/collections.html # collections.MutableMapping) o [DictMixin] (http://docs.python.org/library/userdict.html#UserDict.DictMixin) sería mejor? –

Respuesta

2

Al desempacar el argumento de palabra clave, se crea un nuevo objeto: del tipo dict. Este diccionario contiene las los valores brutos de la configuración (sin interpolación)

Demostración:

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

Para resolver el problema que podría crear una versión ampliada de la configuración de la siguiente manera:

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

Otra forma más elegante es simplemente evitar desempacar: Esto se puede lograr utilizando la función string.Formatter.vformat:

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

Como mi ConfigObj no cambia en el transcurso del guión, todo va a estar bien. Sin embargo, ¡parece algo torpe! –

2

He tenido un problema similar.

Una solución consiste en utilizar la función de configobj ".dict()". Esto funciona porque configobj devuelve un diccionario real, que Python sabe cómo descomprimir.

Su ejemplo se convierte en:

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