How to store and retrieve a dictionary of tuples in config parser python?

♀尐吖头ヾ 提交于 2021-01-28 08:04:45

问题


I'm using the configparser library in python to manage my configuration files.

But, I can't find a method to store and retrieve tuples data-structure through it.

My data is a dictionary of tuples.

name_mapper = {
    0 = (0, 0)
    1 = (0, 1)
    2 = (0, 2)
    3 = (1, 0)
    4 = (1, 1)
    5 = (1, 2)
    6 = (2, 0)
    7 = (2, 1)
    8 = (2, 2)
    9 = (3, 0)
    10 = (3, 1)
    11 = (3, 2)
}

When I write this dictionary via configparser, everything becomes a string.

myconfig.ini

[NAME_MAPPER]
0 = (0, 0)
1 = (0, 1)
2 = (0, 2)
3 = (1, 0)
4 = (1, 1)
5 = (1, 2)
6 = (2, 0)
7 = (2, 1)
8 = (2, 2)
9 = (3, 0)
10 = (3, 1)
11 = (3, 2)

Now, on reading the "my_config.ini"

config = configparser.ConfigParser()
config.read('config_params.ini')
name_mapper = dict(config['NAME_MAPPER'])

But, the dictionary no longer holds tuples, its just tuple formatted as string.

name_mapper = {
    '0' = '(0, 0)'
    '1' = '(0, 1)'
    '2' = '(0, 2)'
    '3' = '(1, 0)'
    '4' = '(1, 1)'
    '5' = '(1, 2)'
    '6' = '(2, 0)'
    '7' = '(2, 1)'
    '8' = '(2, 2)'
    '9' = '(3, 0)'
    '10' = '(3, 1)'
    '11' = '(3, 2)'
}

I figured out a way to correct this by using ast.literal_eval method.

from ast import literal_eval

new_name_mapper = dict()
for each in name_mapper:
    new_name_mapper[int(each)] = literal_eval(name_mapper[each])

Now, new_name_mapper is correctly formatted.

name_mapper = {
    0 = (0, 0)
    1 = (0, 1)
    2 = (0, 2)
    3 = (1, 0)
    4 = (1, 1)
    5 = (1, 2)
    6 = (2, 0)
    7 = (2, 1)
    8 = (2, 2)
    9 = (3, 0)
    10 = (3, 1)
    11 = (3, 2)
}

But I'm sure, its not the best approach. Anyone got better & more pythonic ideas.


回答1:


Config parser will always return Strings, except you use an explicit converter using the getbool getint`` etc methods. However you can write your own converter function and register it with your parser, then use it to retrieve the value any way you like.

From the Configparser Docs:

converters, default value: not set

Config parsers provide option value getters that perform type conversion. By default getint(), getfloat(), and getboolean() are implemented. Should other getters be desirable, users may define them in a subclass or pass a dictionary where each key is a name of the converter and each value is a callable implementing said conversion. For instance, passing {'decimal': decimal.Decimal} would add getdecimal() on both the parser object and all section proxies. In other words, it will be possible to write both parser_instance.getdecimal('section', 'key', fallback=0) and parser_instance['section'].getdecimal('key', 0).

If the converter needs to access the state of the parser, it can be implemented as a method on a config parser subclass. If the name of this method starts with get, it will be available on all section proxies, in the dict-compatible form (see the getdecimal() example above).

So you could write a function to parse the tuple

 >>> def parse_tuple(input):
 ...     return tuple(k.strip() for k in input[1:-1].split(','))

 >>> parse_tuple('(1, 2, 3)')
 >>> ('1', '2', '3')

or if you want ints:

 >>> def parse_int_tuple(input):
 ...     return tuple(int(k.strip()) for k in input[1:-1].split(','))

 >>> parse_int_tuple('(1, 2, 3)')
 >>> (1, 2, 3)

the create your configparser object, passing this converter:

>>> parser = ConfigParser(converters={'tuple': parse_int_tuple})
>>> parser.read_dict({'NAME_MAPPER': name_mapper})
>>> parser['NAME_MAPPER'].gettuple('0')
(0, 0)

IMO this is the most pythonic approach since it uses only well documented functionality



来源:https://stackoverflow.com/questions/56967754/how-to-store-and-retrieve-a-dictionary-of-tuples-in-config-parser-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!