Преобразование ConfigParser.items('') в словарь

Как я могу преобразовать результат ConfigParser.items('section') в словарь для форматирования строки, как здесь:

import ConfigParser

config = ConfigParser.ConfigParser()
config.read('conf.ini')

connection_string = ("dbname='%(dbname)s' user='%(dbuser)s' host='%(host)s' "
                     "password='%(password)s' port='%(port)s'")

print connection_string % config.items('db')

Ответ 1

Это уже сделано для вас в config._sections. Пример:

$ cat test.ini
[First Section]
var = value
key = item

[Second Section]
othervar = othervalue
otherkey = otheritem

И затем:

>>> from ConfigParser import ConfigParser
>>> config = ConfigParser()
>>> config.read('test.ini')
>>> config._sections
{'First Section': {'var': 'value', '__name__': 'First Section', 'key': 'item'}, 'Second Section': {'__name__': 'Second Section', 'otherkey': 'otheritem', 'othervar': 'othervalue'}}
>>> config._sections['First Section']
{'var': 'value', '__name__': 'First Section', 'key': 'item'}

Изменить: Мое решение по той же проблеме было приостановлено, поэтому я еще раз проиллюстрирую, как мой ответ делает то же самое, не передавая раздел через dict(), потому что config._sections предоставляется с помощью модуля для вас уже.

Пример test.ini:

[db]
dbname = testdb
dbuser = test_user
host   = localhost
password = abc123
port   = 3306

Магическое событие:

>>> config.read('test.ini')
['test.ini']
>>> config._sections
{'db': {'dbname': 'testdb', 'host': 'localhost', 'dbuser': 'test_user', '__name__': 'db', 'password': 'abc123', 'port': '3306'}}
>>> connection_string = "dbname='%(dbname)s' user='%(dbuser)s' host='%(host)s' password='%(password)s' port='%(port)s'"
>>> connection_string % config._sections['db']
"dbname='testdb' user='test_user' host='localhost' password='abc123' port='3306'"

Итак, это решение не неправильно, и на самом деле это требует меньшего шага. Спасибо, что остановились!

Ответ 2

Вы пробовали

print connection_string % dict(config.items('db'))

?

Ответ 3

Как я это сделал в одну строчку.

my_config_parser_dict = {s:dict(config.items(s)) for s in config.sections()}

Не больше, чем другие ответы, но когда дело не в реальных методах вашего метода, и вам нужно его просто в одном месте, используйте меньше строк и воспользуйтесь возможностью понимания диктата, что может быть полезным.

Ответ 4

Я знаю, что это было задано давно и выбрано решение, но выбранное решение не учитывает значения по умолчанию и замену переменных. Поскольку это первый удар при поиске созданий dicts от парсеров, я думал, что разместил свое решение, которое включает в себя замены по умолчанию и переменные с помощью ConfigParser.items().

from ConfigParser import SafeConfigParser
defaults = {'kone': 'oneval', 'ktwo': 'twoval'}
parser = SafeConfigParser(defaults=defaults)
parser.set('section1', 'kone', 'new-val-one')
parser.add_section('section1')
parser.set('section1', 'kone', 'new-val-one')
parser.get('section1', 'ktwo')
parser.add_section('section2')
parser.get('section2', 'kone')
parser.set('section2', 'kthree', 'threeval')
parser.items('section2')
thedict = {}
for section in parser.sections():
    thedict[section] = {}
    for key, val in parser.items(section):
        thedict[section][key] = val
thedict
{'section2': {'ktwo': 'twoval', 'kthree': 'threeval', 'kone': 'oneval'}, 'section1': {'ktwo': 'twoval', 'kone': 'new-val-one'}}

Удобная функция для этого может выглядеть примерно так:

def as_dict(config):
    """
    Converts a ConfigParser object into a dictionary.

    The resulting dictionary has sections as keys which point to a dict of the
    sections options as key => value pairs.
    """
    the_dict = {}
    for section in config.sections():
        the_dict[section] = {}
        for key, val in config.items(section):
            the_dict[section][key] = val
    return the_dict

Ответ 5

Для отдельного раздела, например. "general", вы можете сделать:

dict(parser['general'])

Ответ 6

Вот еще один подход, использующий Python 3.7 с configparser и ast.literal_eval:

game.ini

[assets]
tileset = {0:(32, 446, 48, 48), 
           1:(96, 446, 16, 48)}

game.py

import configparser
from ast import literal_eval

config = configparser.ConfigParser()
config.read('game.ini')

# convert a string to dict
tileset = literal_eval(config['assets']['tileset'])

print('tileset:', tileset)
print('type(tileset):', type(tileset))

выход

tileset: {0: (32, 446, 48, 48), 1: (96, 446, 16, 48)}
type(tileset): <class 'dict'>

Ответ 7

Сочетание ответов Мишеля д'Амико и Кайла (без разборчивости) дает менее читабельное, но несколько убедительное выражение:

{i: {i[0]: i[1] for i in config.items(i)} for i in config.sections()}