【问题标题】:Define order of config.ini entries when writing to file with configparser?使用 configparser 写入文件时定义 config.ini 条目的顺序?
【发布时间】:2018-04-08 20:03:49
【问题描述】:

我正在使用Python configparser 生成config.ini 文件来存储我的脚本配置。配置是由代码生成的,但文件的重点是,在后期有一种外部方式来更改以编程方式生成的配置。所以文件需要易于阅读,并且配置选项应该很容易找到。 configparser 中的部分是一种很好的方法,可以确保在一个部分中,条目似乎是随机排序的。例如这段代码:

import configparser
config = configparser.ConfigParser()

config['DEFAULT'] = {
    'shuffle': 'True',
    'augment': 'True',
    # [... some other options ...] 
    'data_layer_type' : 'hdf5',     
    'shape_img' : '[1024, 1024, 4]',    
    'shape_label' : '[1024, 1024, 1]', 
    'shape_weights' : '[1024, 1024, 1]' 
}

with open('config.ini', 'w') as configfile:
    config.write(configfile)

生成一个config.ini-File 的顺序:

[DEFAULT]
shape_weights = [1024, 1024, 1]
# [... some of the other options ...] 
shuffle = True
augment = True
data_layer_type = hdf5
# [... some of the other options ...] 
shape_img = [1024, 1024, 4]
# [... some of the other options ...] 
shape_label = [1024, 1024, 1]

即这些条目既不按字母顺序排列,也不按任何其他可识别的顺序排列。但我想要订单,例如形状选项都在同一个地方,不分发给用户浏览...

Here 声明无序行为在 Python 3.1 中已修复为默认使用有序字典,但我使用的是 Python 3.5.2 并获得无序条目。是否有我需要设置的标志或对 dict 进行排序以使其(至少)按字母顺序排序的条目的方法?

在使用 configparser 以编程方式生成 config.ini 时,有没有办法定义条目的顺序?(Python 3.5)

【问题讨论】:

  • 尝试使用collections.OrderedDict
  • 我做了:from collections import OrderedDict,然后是config = configparser.ConfigParser(dict_type=OrderedDict),但这并没有帮助。输出仍然是无序的(每次运行代码时也不同)。
  • 你的问题是你分配的字典。字典文字是无序的(在 cpython3.5 及以下版本中)。你想要config['DEFAULT'] = collections.OrderedDict(<<<iterable of tuples>>>)
  • 是的,这是有道理的——所以问题是我在执行config['DEFAULT'] = { ... } 时实际上是在将“无序”字典分配给有序字典。你想把它变成我可以接受的答案吗?

标签: python python-3.x config configparser


【解决方案1】:

这里的问题不是 configparser 没有在内部使用 OrderedDicts,而是你正在制作一个无序的文字并分配它。

注意这不是有序的:

>>> x = {
...     'shuffle': 'True',
...     'augment': 'True',
...     # [... some other options ...] 
...     'data_layer_type' : 'hdf5',     
...     'shape_img' : '[1024, 1024, 4]',    
...     'shape_label' : '[1024, 1024, 1]', 
...     'shape_weights' : '[1024, 1024, 1]' 
... }
>>> for k in x:
...     print(k)
... 
shuffle
augment
shape_img
shape_label
shape_weights
data_layer_type

(作为“小字典”优化的一部分,这在 python3.6 中作为实现细节发生了变化(所有字典都变得有序)——由于方便,可能被标准化为 python3.7 的一部分)

这里的解决方法是确保您一直分配OrderedDicts:

config['DEFAULT'] = collections.OrderedDict((
    ('shuffle', 'True'),
    ('augment', 'True'),
    # [... some other options ...] 
    ('data_layer_type', 'hdf5'),     
    ('shape_img', '[1024, 1024, 4]'),    
    ('shape_label', '[1024, 1024, 1]'), 
    ('shape_weights', '[1024, 1024, 1]'), 
))

【讨论】:

    【解决方案2】:

    configparser 似乎默认使用 OrderedDicts(从 Python 2.7 / 3.1 开始),这使得 ConfigParser(dict_type=OrderedDict) 过时了。但是,默认情况下这不会对条目进行排序,仍然需要手动进行(至少在我的情况下)。

    我找到了执行此操作的代码 here 并添加了默认排序:

    import configparser
    from collections import OrderedDict
    
    # [...] define your config sections and set values here
    
    #Order the content of DEFAULT section alphabetically
    config._defaults = OrderedDict(sorted(config._defaults.items(), key=lambda t: t[0]))
    
    #Order the content of each section alphabetically
    for section in config._sections:
        config._sections[section] = OrderedDict(sorted(config._sections[section].items(), key=lambda t: t[0]))
    
    # Order all sections alphabetically
    config._sections = OrderedDict(sorted(config._sections.items(), key=lambda t: t[0] ))
    

    【讨论】:

      猜你喜欢
      • 2011-10-01
      • 1970-01-01
      • 2020-10-17
      • 1970-01-01
      • 2021-10-21
      • 1970-01-01
      • 2014-06-15
      • 2018-01-07
      相关资源
      最近更新 更多