How can I convert the result of a ConfigParser.items('section') to a dictionary to format a string like here:
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')
Have you tried
print connection_string % dict(config.items('db'))
?
How I did it in just one line.
my_config_parser_dict = {s:dict(config.items(s)) for s in config.sections()}
No more than other answers but when it is not the real businesses of your method and you need it just in one place use less lines and take the power of dict comprehension could be useful.
This is actually already done for you in config._sections
. Example:
$ cat test.ini
[First Section]
var = value
key = item
[Second Section]
othervar = othervalue
otherkey = otheritem
And then:
>>> 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'}
Edit: My solution to the same problem was downvoted so I'll further illustrate how my answer does the same thing without having to pass the section thru dict()
, because config._sections
is provided by the module for you already .
Example test.ini:
[db]
dbname = testdb
dbuser = test_user
host = localhost
password = abc123
port = 3306
Magic happening:
>>> 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'"
So this solution is not wrong, and it actually requires one less step. Thanks for stopping by!
I know this was asked a long time ago and a solution chosen, but the solution selected does not take into account defaults and variable substitution. Since it's the first hit when searching for creating dicts from parsers, thought I'd post my solution which does include default and variable substitutions by using 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'}}
A convenience function to do this might look something like:
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
对于单个部分,例如“一般”,您可以执行以下操作:
dict(parser['general'])
In Python +3.6 you could do this
file.ini
[SECTION1]
one = 1
two = 2
[SECTION2]
foo = Hello
bar = World
[SECTION3]
param1 = parameter one
param2 = parameter two
file.py
import configparser
cfg = configparser.ConfigParser()
cfg.read('file.ini')
# Get one section in a dict
numbers = {k:v for k, v in cfg['SECTION1'].items()}
If you need all sections listed you should use cfg.sections()
Another alternative would be:
config.ini
[DEFAULT]
potato=3
[foo]
foor_property=y
potato=4
[bar]
bar_property=y
parser.py
import configparser
from typing import Dict
def to_dict(config: configparser.ConfigParser) -> Dict[str, Dict[str, str]]:
"""
function converts a ConfigParser structure into a nested dict
Each section name is a first level key in the the dict, and the key values of the section
becomes the dict in the second level
{
'section_name': {
'key': 'value'
}
}
:param config: the ConfigParser with the file already loaded
:return: a nested dict
"""
return {section_name: dict(config[section_name]) for section_name in config.sections()}
main.py
import configparser
from parser import to_dict
def main():
config = configparser.ConfigParser()
# By default section names are parsed to lower case, optionxform = str sets to no conversion.
# For more information: https://docs.python.org/3/library/configparser.html#configparser-objects
# config.optionxform = str
config.read('config.ini')
print(f'Config read: {to_dict(config)}')
print(f'Defaults read: {config.defaults()}')
if __name__ == '__main__':
main()
Here is another approach using Python 3.7
with configparser
and 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))
output
tileset: {0: (32, 446, 48, 48), 1: (96, 446, 16, 48)}
type(tileset): <class 'dict'>
结合 Michele d'Amico 和 Kyle 的回答(没有字典),产生了一个不太可读但不知何故引人注目:
{i: {i[0]: i[1] for i in config.items(i)} for i in config.sections()}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.