如何在配置解析器 python 中存储和检索元组字典?
How to store and retrieve a dictionary of tuples in config parser python?
我正在使用 python 中的 configparser 库来管理我的配置文件。
但是,我找不到通过它存储和检索元组数据结构的方法。
我的数据是一个元组字典。
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)
}
当我通过 configparser 写这个字典时,一切都变成了一个字符串。
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)
现在,在阅读 "my_config.ini"
config = configparser.ConfigParser()
config.read('config_params.ini')
name_mapper = dict(config['NAME_MAPPER'])
但是,字典不再包含元组,它只是格式化为字符串的元组。
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)'
}
我找到了一种使用 ast.literal_eval 方法来纠正此问题的方法。
from ast import literal_eval
new_name_mapper = dict()
for each in name_mapper:
new_name_mapper[int(each)] = literal_eval(name_mapper[each])
现在,new_name_mapper 的格式正确了。
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)
}
但我敢肯定,这不是最好的方法。任何人都变得更好和更多 pythonic 创意。
配置解析器将始终 return 字符串,除非您使用 getbool
getint`` 等方法使用显式转换器。然而,您可以编写自己的转换器函数并将其注册到您的解析器,然后使用它以您喜欢的任何方式检索值。
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).
所以你可以写一个函数来解析元组
>>> def parse_tuple(input):
... return tuple(k.strip() for k in input[1:-1].split(','))
>>> parse_tuple('(1, 2, 3)')
>>> ('1', '2', '3')
或者如果你想要整数:
>>> 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)
创建您的 configparser 对象,传递此转换器:
>>> parser = ConfigParser(converters={'tuple': parse_int_tuple})
>>> parser.read_dict({'NAME_MAPPER': name_mapper})
>>> parser['NAME_MAPPER'].gettuple('0')
(0, 0)
IMO 这是最 pythonic 的方法,因为它只使用有据可查的功能
我正在使用 python 中的 configparser 库来管理我的配置文件。
但是,我找不到通过它存储和检索元组数据结构的方法。
我的数据是一个元组字典。
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)
}
当我通过 configparser 写这个字典时,一切都变成了一个字符串。
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)
现在,在阅读 "my_config.ini"
config = configparser.ConfigParser()
config.read('config_params.ini')
name_mapper = dict(config['NAME_MAPPER'])
但是,字典不再包含元组,它只是格式化为字符串的元组。
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)'
}
我找到了一种使用 ast.literal_eval 方法来纠正此问题的方法。
from ast import literal_eval
new_name_mapper = dict()
for each in name_mapper:
new_name_mapper[int(each)] = literal_eval(name_mapper[each])
现在,new_name_mapper 的格式正确了。
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)
}
但我敢肯定,这不是最好的方法。任何人都变得更好和更多 pythonic 创意。
配置解析器将始终 return 字符串,除非您使用 getbool
getint`` 等方法使用显式转换器。然而,您可以编写自己的转换器函数并将其注册到您的解析器,然后使用它以您喜欢的任何方式检索值。
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).
所以你可以写一个函数来解析元组
>>> def parse_tuple(input):
... return tuple(k.strip() for k in input[1:-1].split(','))
>>> parse_tuple('(1, 2, 3)')
>>> ('1', '2', '3')
或者如果你想要整数:
>>> 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)
创建您的 configparser 对象,传递此转换器:
>>> parser = ConfigParser(converters={'tuple': parse_int_tuple})
>>> parser.read_dict({'NAME_MAPPER': name_mapper})
>>> parser['NAME_MAPPER'].gettuple('0')
(0, 0)
IMO 这是最 pythonic 的方法,因为它只使用有据可查的功能