Почему * * kwargs не интерполируется с помощью python ConfigObj?
Я использую ConfigObj в python с интерполяцией в стиле шаблона. Разворачивание моего конфигурационного словаря через **, похоже, не делает интерполяцию. Это особенность или ошибка? Есть хорошие обходные пути?
$ 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
. Почему интерполяция не работает с * * кваргами?
2 ответа:
При распаковке аргумента ключевого слова создается новый объект: типа
dict
. Этот словарь содержит необработанные значения конфигурации (без интерполяции)Демонстрация:
>>> id(config) 31143152 >>> def showKeywordArgs(**kwargs): ... print(kwargs, type(kwargs), id(kwargs)) ... >>> showKeywordArgs(**config) ({'foo': '/test', 'bar': '$foo/directory'}, <type 'dict'>, 35738944)
Чтобы решить эту проблему, вы можете создать расширенную версию конфигурации следующим образом:
Еще один более элегантный способ-это просто избежать распаковки: это может быть достигнуто с помощью функции string.Форматер.vformat :>>> expandedConfig = {k: config[k] for k in config} >>> '{bar}'.format(**expandedConfig) '/test/directory'
import string fmt = string.Formatter() fmt.vformat("{bar}", None, config)
У меня была аналогичная проблема.
Обходной путь заключается в использовании функции configobj ".словарь()". Это работает, потому что configobj возвращает реальный словарь, который Python знает, как распаковать.
Ваш пример становится:
>>> import configobj >>> config = configobj.ConfigObj('my.conf', interpolation='Template') >>> config['bar'] '/test/directory' >>> '{bar}'.format(**config.dict()) '/test/directory'