杰瑞科技汇

Python的configparser如何读写配置文件?

configparser 是 Python 标准库中的一个模块,用于解析和操作符合 INI 格式的配置文件,INI 文件是一种简单、易读的键值对存储格式,非常适合用来存储应用程序的配置信息,如数据库连接、API密钥、开关设置等。

Python的configparser如何读写配置文件?-图1
(图片来源网络,侵删)

什么是 INI 文件?

INI 文件通常由节(Sections)、键(Keys)和值(Values)组成,结构如下:

; 这是一个注释行
[DEFAULT] ; 这是一个默认节,它的键值对会被所有其他节继承
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
[bitbucket.org]
User = hg
[topsecret.server.com]
Port = 50022
ForwardX11 = no
User = timmy
; 下面这个节会继承 [DEFAULT] 的 Compression 和 CompressionLevel
[another.section]
Host = example.com
Port = 8080
ForwardX11 = yes
  • : 由方括号 [] 包围的标题,如 [bitbucket.org]
  • 键-值对: 由 key = value 的形式组成, 两边的空格会被自动忽略。
  • 注释: 以 或 开头的行为注释。
  • [DEFAULT]: 这是一个特殊的节,其中的键值对会作为默认值,被所有其他节继承,除非在特定节中被覆盖。

configparser 的核心类

configparser 模块的核心是 ConfigParser 类,你通常会创建一个 ConfigParser 对象来加载、读取和修改配置文件。


基本用法

1 读取配置文件

假设我们有一个名为 config.ini 的文件,内容如上所示。

步骤:

Python的configparser如何读写配置文件?-图2
(图片来源网络,侵删)
  1. 导入 configparser
  2. 创建一个 ConfigParser 实例。
  3. 调用 read() 方法来加载并解析配置文件。
  4. 通过节名和键名来访问值。
import configparser
# 1. 创建一个 ConfigParser 对象
config = configparser.ConfigParser()
# 2. 读取配置文件
# 如果文件不存在,FileNotFoundError 会被抛出
config.read('config.ini')
# 3. 访问配置项
# 访问 [DEFAULT] 节中的值
print(f"默认压缩级别: {config['DEFAULT']['CompressionLevel']}")
# 访问 [bitbucket.org] 节中的值
# 它会继承 [DEFAULT] 节的 CompressionLevel
print(f"bitbucket.org 的用户: {config['bitbucket.org']['User']}")
print(f"bitbucket.org 的压缩级别: {config['bitbucket.org']['CompressionLevel']}")
# 访问 [topsecret.server.com] 节中的值
print(f"topsecret 的端口: {config['topsecret.server.com']['Port']}")
# 尝试访问不存在的键会引发 KeyError
try:
    print(config['bitbucket.org']['Password'])
except KeyError as e:
    print(f"捕获到预期的 KeyError: {e}")
# 安全地获取值,如果键不存在则返回 None 或默认值
print(f"安全获取 Password: {config.get('bitbucket.org', 'Password', fallback='N/A')}")

2 访问配置项的方法

ConfigParser 提供了多种方法来获取配置项,以适应不同的数据类型需求:

  • config.get(section, option): 获取字符串类型的值。
  • config.getint(section, option): 获取整型 (int) 的值。
  • config.getfloat(section, option): 获取浮点型 (float) 的值。
  • config.getboolean(section, option): 获取布尔型 (bool) 的值。

对于布尔值,configparser 非常智能,它会接受 yes/no, on/off, true/false, 1/0 等多种形式并转换为 TrueFalse

import configparser
config = configparser.ConfigParser()
config.read('config.ini')
# 使用 getint 获取端口号
port = config.getint('topsecret.server.com', 'Port')
print(f"端口 (int 类型): {port}, 类型: {type(port)}")
# 使用 getboolean 获取开关
forward_x11_bitbucket = config.getboolean('bitbucket.org', 'ForwardX11', fallback=False)
forward_x11_topsecret = config.getboolean('topsecret.server.com', 'ForwardX11')
print(f"bitbucket.org 的 ForwardX11: {forward_x11_bitbucket}")
print(f"topsecret.server.com 的 ForwardX11: {forward_x11_topsecret}")

3 修改和写入配置文件

你可以动态地修改配置,并将其写回文件。

步骤:

Python的configparser如何读写配置文件?-图3
(图片来源网络,侵删)
  1. 读取现有文件(如果需要)。
  2. 通过 config['section_name']['key'] = 'new_value' 的方式修改或添加键值对。
  3. 使用 config.write() 方法将修改写回文件。
import configparser
config = configparser.ConfigParser()
config.read('config.ini')
# 修改现有值
config['topsecret.server.com']['Port'] = '55555'
config['bitbucket.org']['ForwardX11'] = 'yes'
# 添加一个新的节和键值对
config['new_section'] = {
    'enabled': 'true',
    'path': '/usr/local/bin'
}
# 添加一个新的键值对到现有节
config['another.section']['debug_mode'] = 'on'
# 将所有更改写入文件
# 使用 'w' 模式会覆盖原文件
with open('config.ini', 'w') as configfile:
    config.write(configfile)
print("配置文件已更新。")

更新后的 config.ini 文件内容如下:

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
[bitbucket.org]
User = hg
ForwardX11 = yes
[topsecret.server.com]
Port = 55555
ForwardX11 = no
User = timmy
[new_section]
enabled = true
path = /usr/local/bin
[another.section]
Host = example.com
Port = 8080
ForwardX11 = yes
debug_mode = on

高级用法与注意事项

1 处理不存在的节或键

直接使用 config['non_existent_section'] 会引发 KeyError,更安全的方式是使用 config.has_section()config.has_option() 进行检查。

if config.has_section('new_section'):
    if config.has_option('new_section', 'enabled'):
        print(f"new_section.enabled 的值是: {config['new_section']['enabled']}")
    else:
        print("new_section 节存在,但没有 enabled 键")
else:
    print("new_section 节不存在")

2 获取所有节、所有键

  • config.sections(): 返回一个包含所有节名的列表(不包括 [DEFAULT])。
  • config.options(section): 返回一个指定节中所有键名的列表。
  • config.items(section): 返回一个指定节中所有 (key, value) 元组的列表。
# 获取所有节名
print("所有节:", config.sections())
# 获取 [another.section] 的所有键和值
print("[another.section] 的所有项:", config.items('another.section'))

3 插值 - 变量替换

configparser 支持一种强大的功能叫做插值,它允许你在一个值中引用另一个值,默认情况下,它使用 BasicInterpolation,它会用 %(key)s 的语法来引用同一节中的其他键。

示例文件 interpolation.ini:

[Paths]
home_dir = /Users
database_dir = %(home_dir)/data

Python 代码:

import configparser
config = configparser.ConfigParser(interpolation=configparser.BasicInterpolation())
config.read('interpolation.ini')
# database_dir 的值会被替换为 /Users/data
print(f"数据库目录: {config['Paths']['database_dir']}") 

4 处理中文编码

在 Python 3 中,configparser 默认使用 UTF-8 编码读取文件,如果你的配置文件是其他编码(如 GBK),你需要在读取时指定编码。

# 假设 config_gbk.ini 是 GBK 编码的文件
config = configparser.ConfigParser()
# 在 read 方法中指定编码
config.read('config_gbk.ini', encoding='gbk')

configparser vs. json / yaml

对于配置文件,configparserJSONYAML 都是常见选择,各有优劣:

特性 configparser (INI) JSON YAML
可读性 ,结构简单 高,但不如 INI 直观 非常高,专为人类可读设计
数据类型 弱类型(默认字符串),有 getint 等辅助方法 强类型(字符串、数字、布尔、数组、对象) 强类型,非常丰富
注释 支持( 或 ) 不支持(标准 JSON 不支持注释) 支持
数据结构 主要是键值对,有节的概念 支持复杂的嵌套结构 支持复杂的嵌套结构,列表等
标准库 ,无需安装 json 模块 ,需要安装 PyYAML
最佳场景 简单的、分组的配置,如 .gitconfig, pip.conf Web API 数据交换,简单的配置文件 复杂的、分层的配置文件,如 Docker Compose, Kubernetes
  • 如果你只需要一个简单、易读、分组的配置文件,并且希望不依赖第三方库,configparser 是绝佳选择。
  • 如果你的配置非常复杂,包含嵌套结构、列表,并且需要支持注释,YAML 是更好的选择。
  • JSON 虽然不能直接写注释,但在很多 Python 项目中也常被用作配置文件格式,尤其是在需要与其他系统交互时。
分享:
扫描分享到社交APP
上一篇
下一篇