Python3 configparser 模块及应用

🎉摘要:Python 是一门解释型、面向对象、动态类型的高级编程语言,由荷兰程序员 Guido van Rossum 于 1991 年发布,核心设计理念是优雅、明确、简单。

在 Python 中,configparser 模块专用来读写、修改 .ini 格式的配置文件。

如果你曾经修改过 Windows 系统中的 MySQL 配置,那么对 ini 类型配置文件应该不陌生,下面是一部分 MySQL 配置数据:

[mysqld]
port=3306
bind-address=0.0.0.0

[mysql]
default-character-set=utf8mb4

[client]
port=3306
default-character-set=utf8mb4
...

.ini 配置文件格式

在使用 configparser 模块操作 .ini 文件之前,我们需要先了解了解 .ini 文件的格式。

文件固定格式如下:

[section]      # 节点(必须用 [] 包裹)
key = value    # 键值对(配置项,可以存在多个)
key2: value2   # 支持 = 或 : 两种写法

[mysql]
host = 127.0.0.1
port = 3306
user = root

简单说明:

  • 大小写不敏感,Host 和 host 相同

  • 支持注释(# 或 ; 开头)

  • 支持多节点分类管理

常用方法

创建配置对象

先使用 import 导入 configparser 模块,然后通过 configparser.ConfigParser() 创建一个标准解析器,示例代码如下:

import configparser

# 创建一个标准解析器
config = configparser.ConfigParser()

读取配置文件

如果配置文件已经存在,配置文件名称为 config.init,配置内容如下:

[mysql]
host = 192.168.1.100
port = 3306

[app]
debug = False
version = 2.1

可以使用 read() 函数读取,该函数直接指定文件名和读取编码,如下:

import configparser

# 创建一个标准解析器
config = configparser.ConfigParser()

# 使用 UTF-8 编码读取 config.ini 文件
config.read('config.ini', encoding='utf-8')

注意:如果 read() 方法指定的配置文件不存在,不会抛出错误。

获取所有节点

当使用 read() 方法读取了 config.ini 配置文件后,我们可以使用 sections() 方法获取配置文件中所有的节点,例如:

import configparser

# 创建一个标准解析器
config = configparser.ConfigParser()

# 使用 UTF-8 编码读取 config.ini 文件
config.read('config.ini', encoding='utf-8')

# 打印所有section节点
print(config.sections()) # ['mysql', 'app']

注意,上面代码 config.sections() 将获取所有的节点。

判断节点是否存在

在实际开发中,当我们要获取某个配置前,可以通过 has_section() 方法检查节点是否存在,如果存在,则返回 True。不存在,则返回 False。例如:

import configparser

# 创建一个标准解析器
config = configparser.ConfigParser()

# 使用 UTF-8 编码读取 config.ini 文件
config.read('config.ini', encoding='utf-8')

# 打印所有section节点
if config.has_section('mysql'):
    print(config['mysql']) # <Section: mysql>
else:
    print("节点 'mysql' 没有发现")

执行上述代码,将执行 if 语句中的代码块。

获取节点下所有键

当我们通过 has_section() 确认节点存在,接下来可以使用 options() 方法获取指定节点下所有的配置键,例如:

import configparser

# 创建一个标准解析器
config = configparser.ConfigParser()

# 使用 UTF-8 编码读取 config.ini 文件
config.read('config.ini', encoding='utf-8')

# 打印所有section节点
if config.has_section('mysql'):
    allKey = config.options('mysql')
    print(allKey) # ['host','port']
else:
    print("节点 'mysql' 没有发现")

注意,上述代码运行后 mysql 节点下仅仅存在一个配置键 host。

获取配置值

获取配置值是 configparser 模块非常重要的功能,我们可以通过 get() 方法获取字符串值,通过  getint() 方法获取整数类型值,通过 getfloat() 方法获取浮点数类型的值,通过 getboolean() 方法获取布尔类型的值,例如:

import configparser

# 创建一个标准解析器
config = configparser.ConfigParser()

# 使用 UTF-8 编码读取 config.ini 文件
config.read('config.ini', encoding='utf-8')

if config.has_section('mysql'):
    # 字符串(默认)
    print(config.get('mysql', 'host')) # 192.168.1.100
    # 整数
    print(config.getint('mysql', 'port')) # 3306

if config.has_section('app'):
    # 浮点数
    print(config.getfloat('app', 'version')) # 2.1
    # 布尔值(支持 yes/no/on/off/true/false)
    print(config.getboolean('app', 'debug')) # False

注意,如果指定的配置 key 不存在,将抛出错误信息,如“configparser.NoOptionError: No option 'host2' in section: 'mysql'”表示在 mysql 节点下面没有名为 host2 的配置信息。

添加/修改配置

我们可以通过 add_section() 方法创建一个新的、空的节点。使用 set() 方法为指定节点添加配置,如果配置存在,则覆盖配置数据。如果不存在,则新增配置。例如:

import configparser

# 创建一个标准解析器
config = configparser.ConfigParser()

# 使用 UTF-8 编码读取 config.ini 文件
config.read('config.ini', encoding='utf-8')

# 添加节点
config.add_section('new_section')

# 修改/添加配置项
config.set('mysql', 'password', '123456')

# 保存修改后的配置到文件
with open('config.ini', 'w', encoding='utf-8') as configfile:
    config.write(configfile)

运行上述脚本,修改 config.ini 后内容如下图:

注意了:

  • 如果节点已经存在,调用 add_section() 方法将抛出“configparser.DuplicateSectionError: Section 'new_section' already exists”错误。此时,我们可以使用 has_section() 方法判断节点是否存在,不存在才进行创建。

  • 如果节点不存在,调用 set() 方法设置参数将抛出“configparser.NoSectionError: No section: 'mysql2'”错误信息。

import configparser

# 创建一个标准解析器
config = configparser.ConfigParser()

# 使用 UTF-8 编码读取 config.ini 文件
config.read('config.ini', encoding='utf-8')

# 添加节点(先判断节点是否存在,不存在才创建)
if not config.has_section('new_section'):
    config.add_section('new_section')

# 仅当节点存在时,才修改其中的值
if config.has_section('mysql2'):
    config.set('mysql2', 'password', '123456')

删除配置

如果你要删除整个节点,包含节点配置,请使用 remove_section() 方法,如果仅仅删除某个键,请使用 remove_option() 方法,例如:

import configparser

# 创建一个标准解析器
config = configparser.ConfigParser()

# 使用 UTF-8 编码读取 config.ini 文件
config.read('config.ini', encoding='utf-8')

# 删除整个节点
if config.has_section('new_section'):
    config.remove_section('new_section')

# 删除某个键
if config.has_section('mysql'):
    config.remove_option('mysql', 'password')

# 保存修改后的配置到文件
with open('config.ini', 'w', encoding='utf-8') as configfile:
    config.write(configfile)

保存配置到文件

在 configparser 模块中,可以通过 write() 方法将修改编辑过的 config 对象保存到 config.ini 文件,例如:

import configparser

# 创建一个标准解析器
config = configparser.ConfigParser()

# 使用 UTF-8 编码读取 config.ini 文件
config.read('config.ini', encoding='utf-8')

# 添加节点(先判断节点是否存在,不存在才创建)
if not config.has_section('new_section'):
    config.add_section('new_section') # 添加节点

# 添加键值对
config.set('new_section', 'name', 'python')

# 保存修改后的配置到文件
with open('config.ini', 'w', encoding='utf-8') as configfile:
    config.write(configfile)

实战示例

下面示例提供完整的示例,供学习参考。

创建并写入配置文件

使用 configparser 模块快速创建 .ini 配置文件,配置文件名为 config.ini,你可更具自己的喜好进行修改。完整代码如下:

import configparser

# 创建配置对象
config = configparser.ConfigParser()

# 添加节点和配置
config['mysql'] = {
    'host': '127.0.0.1',
    'port': 3306,
    'user': 'root',
    'password': 'root123'
}

config['redis'] = {
    'host': '127.0.0.1',
    'port': 6379,
    'db': 0
}

config['app'] = {
    'name': 'test_app',
    'debug': 'true',
    'version': 1.0
}

# 保存到文件
with open('config.ini', 'w', encoding='utf-8') as f:
    config.write(f)

print("配置文件创建完成!")

运行后生成 config.ini 配置文件的内容如下:

[mysql]
host = 127.0.0.1
port = 3306
user = root
password = root123

[redis]
host = 127.0.0.1
port = 6379
db = 0

[app]
name = test_app
debug = true
version = 1.0

读取配置文件

假如我们已经存在了 config.ini 配置文件,可以通过 configparser 来读取改配置中的内容,例如:

import configparser

# 读取文件
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8')

# 获取所有节点
print("所有节点:", config.sections())

# 读取 MySQL 配置
host = config.get('mysql', 'host')
port = config.getint('mysql', 'port')
user = config.get('mysql', 'user')
print(f"\nMySQL:{host}:{port} 用户:{user}")

# 读取 Redis
redis_host = config['redis']['host']
redis_port = config['redis']['port']
print(f"Redis:{redis_host}:{redis_port}")

# 读取布尔值、浮点数
debug = config.getboolean('app', 'debug')
version = config.getfloat('app', 'version')
print(f"App 调试模式:{debug},版本:{version}")

运行结果后,输出结果如下:

所有节点: ['mysql', 'redis', 'app']

MySQL:127.0.0.1:3306 用户:root
Redis:127.0.0.1:6379
App 调试模式:True,版本:1.0

注意,如果配置文件不存在,获取配置的值将会报错(如节点不存在,具体配置项不存在)。

优化后的代码如下:

import configparser

# 读取文件
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8')

# 获取所有节点
print("所有节点:", config.sections())

# 读取 MySQL 配置
if config.has_section('mysql'):
    mysqlConfig = config.options('mysql')  # 获取 mysql 节点下的所有选项
    # 获取配置,先判断是否存在该选项
    host = config.get('mysql', 'host') if 'host' in mysqlConfig else ''
    port = config.getint('mysql', 'port') if 'port' in mysqlConfig else ''
    user = config.get('mysql', 'user') if 'user' in mysqlConfig else ''
    print(f"\nMySQL:{host}:{port} 用户:{user}")

# 读取 Redis
if config.has_section('redis'):
    redisConfig = config.options('redis')
    redis_host = config['redis']['host'] if 'host' in redisConfig else ''
    redis_port = config['redis']['port'] if 'port' in redisConfig else ''
    print(f"Redis:{redis_host}:{redis_port}")

# 读取布尔值、浮点数
if config.has_section('app'):
    appConfig = config.options('app')
    debug = config.getboolean('app', 'debug') if 'debug' in appConfig else False
    version = config.getfloat('app', 'version') if 'version' in appConfig else 0.0
    print(f"App 调试模式:{debug},版本:{version}")

修改 & 删除配置

如果我们使用 .ini 配置文件动态保存一些配置信息,如允许用户设置某些参数,那么就需要用到修改或删除。通常,程序默认提供了一套配置,用户根据自己的喜好修改部分值,如下载路径、主题颜色、字体等等。

示例:修改密码、删除 redis 配置

import configparser

config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8')

# 修改 MySQL 密码
if not config.has_section('mysql'):
    config.add_section('mysql')
config.set('mysql', 'password', 'new_password_666')

# 添加新配置项
if not config.has_section('app'):
    config.add_section('app')
config.set('app', 'author', 'python_test')

# 删除 Redis 的 db 配置
if config.has_section('redis'):
    config.remove_option('redis', 'db')

# 保存
with open('config.ini', 'w', encoding='utf-8') as f:
    config.write(f)

print("修改保存完成!")

运行上面脚本,修改前配置内容如下:

修改后的配置如下:

封装工具类

虽然 configparser 模块提供了对 .ini 文件的操作方法,但是要安全的、正确的处理配置,还是有点麻烦,我们可以封装一个工具类,专门用来管理 .ini 文件。提供的功能如下:

  1. 自动加载配置文件,默认使用 config.ini 配置文件名

  2. 支持读取各类数据(string/int/float/bool)

  3. 支持动态修改并保存

完整代码:

import configparser
import os

# 定义配置工具类
class ConfigTool:
    """
    初始化配置管理器
    参数:
        config_path: 配置文件路径,默认为'config.ini'
    说明:
        如果配置文件存在则读取,不存在则创建空文件
    """
    def __init__(self, config_path='config.ini'):
        self.config_path = config_path
        self.config = configparser.ConfigParser()
        # 读取配置(不存在则创建空文件)
        if os.path.exists(config_path):
            self.config.read(config_path, encoding='utf-8')
        else:
            with open(config_path, 'w', encoding='utf-8') as f:
                self.config.write(f)

    def get_str(self, section, key, default=None):
        """
        获取配置文件中的字符串
        参数:
            section: 配置节点
            key: 配置项
            default: 默认值(如果配置项不存在则返回该值)
        """
        # 判断配置文件中是否存在该节点
        if self.config.has_option(section, key):
            # 判断节点下面是否存在配置项,存在,则返回,不存在,则返回默认值
            return self.config.get(section, key) if key in self.config.options(section) else default
        return default

    def get_int(self, section, key, default=None):
        """
        获取配置文件中的整数
        参数:
            section: 配置节点
            key: 配置项
            default: 默认值(如果配置项不存在则返回该值)
        """
        if self.config.has_option(section, key):
            return self.config.getint(section, key) if key in self.config.options(section) else default
        return default

    def get_float(self, section, key, default=None):
        """
        获取配置文件中的浮点数
        参数:
            section: 配置节点
            key: 配置项
            default: 默认值(如果配置项不存在则返回该值)
        """
        if self.config.has_option(section, key):
            return self.config.getfloat(section, key) if key in self.config.options(section) else default
        return default

    def get_bool(self, section, key, default=None):
        """
        获取配置文件中的布尔值
        参数:
            section: 配置节点
            key: 配置项
            default: 默认值(如果配置项不存在则返回该值)
        """
        if self.config.has_option(section, key):
            return self.config.getboolean(section, key) if key in self.config.options(section) else default
        return default

    def set(self, section, key, value):
        """
        设置配置项
        参数:
            section: 配置节点
            key: 配置项
            value: 配置值
        """
        if not self.config.has_section(section):
            self.config.add_section(section)
        self.config.set(section, key, str(value))
        self.save()

    def del_section(self, section):
        """
        删除配置节点
        参数:
            section: 配置节点
        """
        if self.config.has_section(section):
            self.config.remove_section(section)
            self.save()

    def del_option(self, section, key):
        """
        删除配置项
        参数:
            section: 配置节点
            key: 配置项
        """
        if self.config.has_section(section):
            self.config.remove_option(section, key)
            self.save()

    def save(self):
        """
        保存配置到文件
        """
        with open(self.config_path, 'w', encoding='utf-8') as f:
            self.config.write(f)


if __name__ == '__main__':
    cf = ConfigTool()

    # 写入配置
    cf.set('mysql', 'host', '192.168.1.100')
    cf.set('mysql', 'port', 3306)
    cf.set('app', 'debug', False)
    cf.set('app', 'version', 2.1)

    # 读取配置
    print("MySQL Host:", cf.get_str('mysql', 'host'))
    print("MySQL Port:", cf.get_int('mysql', 'port'))
    print("App Debug:", cf.get_bool('app', 'debug'))
    print("App Version:", cf.get_float('app', 'version'))

    # 删除配置
    cf.del_option('mysql', 'port')
    print("删除 port 成功")

如果直接运行上述脚本,将自动创建 config.ini,写入配置,读取并打印和删除指定项并保存。

关于 configparser 模块更多知识请参考 https://docs.python.org/3/library/configparser.html 文档。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号