Convert ConfigParser.items('') to dictionary

后端 未结 9 1082
再見小時候
再見小時候 2020-12-12 18:44

How can I convert the result of a ConfigParser.items(\'section\') to a dictionary to format a string like here:

import ConfigParser

config = ConfigParser.Co         


        
相关标签:
9条回答
  • 2020-12-12 19:16

    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.

    0 讨论(0)
  • 2020-12-12 19:28

    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!

    0 讨论(0)
  • 2020-12-12 19:29

    Have you tried

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

    ?

    0 讨论(0)
  • 2020-12-12 19:32

    Combining Michele d'Amico and Kyle's answer (no dict), produces a less readable but somehow compelling:

    {i: {i[0]: i[1] for i in config.items(i)} for i in config.sections()}
    
    0 讨论(0)
  • 2020-12-12 19:35

    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()
    
    0 讨论(0)
  • 2020-12-12 19:40

    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
    
    0 讨论(0)
提交回复
热议问题