ConfigObj/ConfigParser 与为 Python 设置文件使用 YAML
Posted
技术标签:
【中文标题】ConfigObj/ConfigParser 与为 Python 设置文件使用 YAML【英文标题】:ConfigObj/ConfigParser vs. using YAML for Python settings file 【发布时间】:2011-03-27 13:03:51 【问题描述】:为 Python 程序创建设置文件,内置模块(ConfigParser)或独立项目(ConfigObj),或使用 YAML 数据序列化格式,哪个更好?我听说 ConfigObj 比 ConfigParser 更容易使用,尽管它不是内置库。我还读到 PyYAML 很容易使用,尽管 YAML 需要一些时间来使用。除了易于实施之外,哪个是创建设置/配置文件的最佳选择?
【问题讨论】:
【参考方案1】:这取决于您想在配置文件中存储什么以及如何使用它们
如果您进行往返(yaml→code→yaml)并希望保留 cmets,则不能使用 PyYAML
或 ConfigParser
。
如果您想保留键的顺序(例如,当您检入配置文件时),PyYAML
不会这样做,除非您指定 !!omap
(这使得更新比普通映射更容易)
如果您想要具有包含映射/字典的未命名元素列表的复杂结构,那么 ConfigParser
和 ConfigObj
将无济于事,因为 INI 文件的键值对必须进入部分并且列表只能成为价值观。
YAML 阅读器的ruamel.yaml
实现支持上述所有¹。很长一段时间以来,我一直使用fuzzyman 出色的ConfigObj 来保存往返评论,以及使用PyYAML 来处理更复杂的结构,这结合了两全其美。 ruamel.yaml
包括 yaml
实用程序,可以将 ConfigObj
INI 文件转换为 YAML
¹ ruamel.yaml 是一个支持 YAML 1.2 的 YAML 库(我建议使用它,但我是该包的作者)。 PyYAML 仅支持(大部分)YAML 1.1。
【讨论】:
我错过了一个免责声明,即这篇文章的作者也是ruamel.yaml
的作者。
@xmedeko 这是(shameless plug)
所指的地方,但我承认它应该更明确(正如我在后面的答案中所做的那样,如here 和here 这个答案是从右边开始的在我开始发布 ruamel.yaml 之后。【参考方案2】:
使用 ConfigObj 至少非常简单,并且 general 中的 ini 文件比 YAML 更简单(并且使用更广泛)。对于更复杂的情况,包括验证、默认值和类型,ConfigObj 提供了一种通过 configspec 验证来执行此操作的方法。
使用 ConfigObj 读取 ini 文件的简单代码:
from configobj import ConfigObj
conf = ConfigObj('filename.ini')
section = conf['section']
value = section['value']
它会自动为您处理列表值并允许多行值。如果您修改配置文件,您可以将其写回,同时保留 order 和 cmets。
有关更多信息,请参阅这些文章,包括类型验证的示例:
http://www.voidspace.org.uk/python/articles/configobj.shtml http://www.blog.pythonlibrary.org/2010/01/01/a-brief-configobj-tutorial/ http://showmedo.com/videotutorials/video?name=10620000&fromSeriesID=1062【讨论】:
【参考方案3】:ConfigParser 有一个非常糟糕的 API,ConfigObj 应该很好但我从未使用过它,对于 ini 文件我通常实现自己的解析器。
然而,类似 ini 的格式并不能很好地处理不同的类型、序列或递归映射,所以我只会使用 yaml。使用编辑器很容易阅读和编辑,有解析这些文件的标准,并且您没有提到的类似 ini 格式的缺点。
【讨论】:
ConfigObj 可以很好地处理类型和序列 :-)以上是关于ConfigObj/ConfigParser 与为 Python 设置文件使用 YAML的主要内容,如果未能解决你的问题,请参考以下文章
整首歌的 mfcc 与为同一首歌的片段计算的 mfcc 不同
WCF 生成的 wsdl 与为创建 WCF 服务而提供的原始 wsdl 不同?
在滚动散列中,散列函数的除法方法中使用的素数与为数字选择的基数之间的关系是啥?
AADSTS50011:请求中指定的回复 URL 与为应用程序配置的回复 URL 不匹配:'**********-*****-*****-**** *****'