【问题标题】:Python's ConfigParser unique keys per sectionPython 的 ConfigParser 每个部分的唯一键
【发布时间】:2008-11-13 18:20:11
【问题描述】:

我阅读了the docs 的部分并看到ConfigParser 返回一个部分中选项的键/值对列表。我认为键在一个部分中不需要是唯一的,否则解析器只会返回一个映射。我围绕这个假设设计了我的配置文件架构,然后遗憾地意识到事实并非如此:

>>> from ConfigParser import ConfigParser
>>> from StringIO import StringIO
>>> fh = StringIO("""
... [Some Section]
... spam: eggs
... spam: ham
... """)
>>> parser = ConfigParser()
>>> parser.readfp(fh)
>>> print parser.items('Some Section')
[('spam', 'ham')]

然后我回去发现文档中我应该阅读的部分:

节通常存储在一个 内置字典。替代 字典类型可以传递给 ConfigParser 构造函数。例如, 如果传递了字典类型 对其键进行排序,部分将是 在回写时排序,将是 每个部分中的键。

为了保留我现有的配置文件方案(我现在真的很喜欢;),我正在考虑传递一个如上所述的类似映射的对象,它会累积值而不是破坏它们。有没有更简单的方法来防止我缺少的键/值崩溃?而不是制作一个疯狂的适配器(如果ConfigParser 的实现发生变化,它可能会中断)我应该只编写ConfigParser 本身的变体吗?

我觉得这可能是我只看到困难解决方案的那些“duh”时刻之一。

[编辑:]下面是一个更精确的示例,说明我希望如何多次使用同一个键:

[Ignored Paths]
ignore-extension: .swp
ignore-filename: tags
ignore-directory: bin

我不喜欢逗号分隔列表语法,因为当您将其缩放到多个值时,它会让人难以接受;例如,以逗号分隔的 50 个扩展名列表不会特别易读。

【问题讨论】:

  • 我认为使用列表比 50 行 'ignore-extension:...' 更具可读性
  • 真的吗?我不同意......每个单独的行你可以扫描列表 - 我从来没有发现逗号分隔的三字母扩展列表很漂亮。我还预计人们希望轻松评论任何给定的选项,这有利于单独的行。

标签: python configuration-files


【解决方案1】:

ConfigParser 并非旨在处理此类情况。此外,您的配置文件对我来说没有意义。

ConfigParser 为每个部分提供了一个类似于 dict 的结构,因此当您调用 parser.items(section) 时,我期待与 dict.items() 类似的输出,它只是键/值元组的列表。我从没想过会看到这样的东西:

[('spam', 'eggs'), ('spam', 'ham')]

更不用说,您希望以下行为如何?:

parser.get('Some Section', 'spam')

这是检索值的预期方式。

如果你想为同一个键存储多个值,我建议在你的配置文件中这样写:

[Some Section]
spam: eggs, ham

这在你的代码中:

spam_values = [v.strip() for v in parser.get('Some Section', 'spam').split(',')]

当然,这仅适用于本身不包含逗号或不处理引号的值。为此,您应该采用更高级的技术(参见thisthis)。

编辑:如果您不介意额外的依赖,您可以查看ConfigObj,它本机支持列表作为值类型。

【讨论】:

  • 我希望parser.get 返回与键关联的第一个或最后一个值。我希望配置被 internally 存储为项目。我不喜欢列表语法,因为它更难观察,但我可能不得不切换。
  • 我在推测,但我认为 dict 将是一个更有效的部分基类。如果是这种情况,它将解释这种行为。无论哪种方式,你都会让自己非常头疼,试图让它做你想做的事。
  • 很公平。我有足够的头痛原样。 :)
【解决方案2】:

ConfigParser 的这个缺陷是 pyglet 使用patched version of epydoc 将 ConfigParser ini 替换成这个simple format 的原因:

name: pyglet
url: http://www.pyglet.org/

output: html
target: doc/api/
...    
module: pyglet

exclude: pyglet.gl.gl
exclude: pyglet.gl.agl
exclude: pyglet.gl.lib_agl
exclude: pyglet.gl.wgl
...

如果您不需要部分 - 这种方法可能很有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多