Python中包含键值对列表的配置文件

25 投票
6 回答
41538 浏览
提问于 2025-04-11 09:26

我有一个Python脚本,它会分析一组错误信息,并检查每条信息是否符合某种模式(正则表达式),目的是把这些信息归类。比如说,“文件x不存在”和“文件y不存在”这两条信息都符合“文件.*不存在”这个模式,所以它们会被归为“文件未找到”这一类,算作两次出现。

随着模式和类别的增多,我想把这些“正则表达式/显示字符串”放到一个配置文件里,基本上就是一种字典的序列化。

我希望这个文件可以手动编辑,所以我不想用任何二进制的序列化方式,也不想用XML序列化,以避免处理字符转义的问题(比如&、<、>等等)。

你有什么好的建议可以实现这个目标吗?

更新:感谢Daren Thomas和Federico Ramponi的帮助,但我不能使用外部的Python文件,里面可能会有任意代码。

6 个回答

8

我听说 ConfigObj 比 ConfigParser 更好用。很多大项目,比如 IPython、Trac 和 Turbogears 都在用它。

在他们的 介绍 中提到:

ConfigObj 是一个简单但功能强大的配置文件读取和写入工具,能轻松处理 ini 文件。它的主要特点是使用起来非常简单,程序员界面直观,配置文件的语法也很简单。不过,它还有很多其他功能:

  • 可以有嵌套的部分(子部分),层级不限
  • 支持列表值
  • 支持多行值
  • 支持字符串插值(替换)
  • 集成了强大的验证系统
    • 包括自动类型检查和转换
    • 支持重复的部分
    • 可以设置默认值
  • 在写出配置文件时,ConfigObj 会保留所有注释和成员、部分的顺序
  • 有很多实用的方法和选项来处理配置文件(比如 'reload' 方法)
  • 完全支持 Unicode
39

我有时候会写一个叫做 config.py 的 Python 模块(也就是一个文件),里面的内容大概是这样的:

config = {
    'name': 'hello',
    'see?': 'world'
}

然后可以这样“读取”它:

from config import config
config['name']
config['see?']

很简单。

36

你有两个不错的选择:

  1. 使用Python自带的配置文件格式,利用ConfigParser
  2. 使用YAML,可以用像PyYAML这样的库

标准的Python配置文件看起来像INI文件,里面有[sections]key : value或者key = value这样的键值对。这种格式的优点是:

  • 不需要额外的第三方库
  • 简单,大家都熟悉的文件格式。

YAML则不同,它是为了让人更容易理解而设计的数据格式,而不仅仅是为了配置。它非常易读,并且提供了几种不同的方式来表示相同的数据。对于你的问题,你可以创建一个这样的YAML文件:

file .* does not exist : file not found
user .* not found : authorization error

或者像这样:

{ file .* does not exist: file not found,
  user .* not found: authorization error }

使用PyYAML非常简单:

import yaml

errors = yaml.load(open('my.yaml'))

到这个时候,errors就是一个符合预期格式的Python字典。YAML不仅能表示字典,如果你更喜欢用一对对的列表,可以用这种格式:

-
  - file .* does not exist 
  - file not found
-
  - user .* not found
  - authorization error

或者

[ [file .* does not exist, file not found],
  [user .* not found, authorization error]]

这样在调用yaml.load时会生成一个列表的列表。

YAML的一个优点是,你可以用它把现有的硬编码数据导出到文件中,创建初始版本,而不是通过复制粘贴和一堆查找替换来把数据弄成正确的格式。

YAML格式可能需要花点时间去熟悉,但使用PyYAML比使用ConfigParser还要简单,优势在于你可以有更多的选择来表示数据。

这两种方式都能满足你当前的需求,ConfigParser更容易上手,而YAML在将来如果需求增加时会给你更多的灵活性。

祝你好运!

撰写回答