社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

用 Python 内置模块处理 ini 配置文件

Python中文社区 • 4 年前 • 576 次点击  

简介

开发人员每天都在处理一些大型而复杂的项目, 而配置文件会帮到我们并节省不少时间。在处理配置文件过程中,无需更改源代码本身,只需要调整配置文件即可访问不同的API接口、更新基础URL信息或其它事情。

尽管可以通过多种方式来支持软件中的配置文件,包括JSON,YAML和纯文本文件,但本文旨在向您介绍 Python 标准库中的configparser模块。

注意:本文基于Python 3.9.0(CPython)。可以在GitHub上找到源代码。(https://github.com/DahlitzFlorian/how-to-work-with-config-files-in-python-article-snippets

文件结构

在编写代码之前,让我们看一下实际配置文件的结构。

[DEFAULT]
admin_page = no
landing_page = yes
moderator_page = no  # looks good here

[moderator]
moderator_page = yes

[admin]
admin_page = yes
moderator_page = yes

在当前的示例中,我们有一个名为config.ini的配置文件。它由三个部分组成,每个部分都由一个标题和一个键-值对列表组成,该标题封装在方括号内。

moderatoradmin模块只是键值对的集合,但DEFAULT模块(第一个模块)有些特殊。如果其他模块之一未提供某个键的值,则它就会包含默认值。因此,如果您想尝试访问其他模块中的值,但该键不存在,则解析器将从默认部分(如果存在)中返回该值,而不是引发KeyError

在本例中,我们通过此配置文件管理用户的页面访问。因此,默认部分代表普通用户的权限,而moderatoradmin模块分别包含协管员和管理员的权限。

访问文件的内容

ConfigParser对象是主要的配置解析器和configparser模块的主要对象。您可以使用映射协议实现自己的配置解析器,让我们继续看看本文中的ConfigParser

尽管ConfigParser接受很多参数,但我们将使用本文的默认值。让我们在工作目录中创建一个名为parser_playground.py的新文件。首先,我们从configparser模块导入ConfigParser类,并创建该类的实例。

# parser_playground.py
from configparser import ConfigParser

config = ConfigParser()

我们的配置对象不包含任何信息, 要更改此设置,我们需要先读取config.ini文件。这可以通过调用ConfigParser实例(此处为config)的read()方法来完成。

# previous code in parser_playground.py
config.read("config.ini")

读取配置文件后,我们可以开始探索如何访问其中存储的信息。首先,我们要列出所有可用的部分。这可以通过使用ConfigParsersections()方法来实现:

# previous code in parser_playground.py
print(f"Sections: {config.sections()}")  # Sections: ['moderator', 'admin']

此外,我们可以使用解析器的has_section()方法检查某个模块是否存在:

# previous code in parser_playground.py
print(f'Does a section called "admin" exist: {config.has_section("admin")}')  # True
print(f'Does a section called "user" exist: {config.has_section("user")}')  # False
print(f'Does a section called "DEFAULT" exist: {config.has_section("DEFAULT")}')  # False

注意:调用sections()方法时,既未列出默认模块·,也没有被has_section()方法确认。

接下来,我们要访问各个值。但是在使用其标识符访问特定值之前,我们可以使用options()方法列出一个模块的所有可用选项,并提供模块名作为参数:

# Previous code in parser_playground.py
print(f'Options: {config.options("admin")}')  # Options: ['admin_page', 'moderator_page', 'landing_page']

此外,我们可以利用has_option()方法来检查给定部分是否包含某个选项:

# Previous code in parser_playground.py
print(f'"admin_page" in "admin" section: {config.has_option("admin""admin_page")}')

要访问模块的值,可以使用解析器的get()方法并提供区域名称和选项名称。这些值将始终为字符串(如果存在)。如果需要其他格式的文件,请考虑使用相应的getboolean()getint()getfloat()方法。他们将尝试将字符串解析为所需的数据类型。

总结本节内容时有个概念需要提到,它就是映射协议访问。这个通用名称意味着可以像处理字典一样访问值。也就是说,我们可以使用config [“ section”] [“ option”]类似的方法来访问某个值,甚至检查某个模块中是否存在某个选项:

# Previous code in parser_playground.py
print("admin_page" in config["admin"])  # True
print(config["admin"]["admin_page"])  # yes

如何修改信息

接下来,让我们看一下如何添加或更改信息并将其写回到配置文件中。同样,我们从模块开始。要添加一个模块,我们可以使用ConfigParseradd_section()方法。它接受模块名称作为字符串,并将相应模块添加到解析器。提供不同的数据类型会导致TypeError 。如果该模块已经存在,则会引发DuplicateSectionError。尝试将该模块命名为默认值会导致ValueError

# Previous code in parser_playground.py
config.add_section("unknown")
print(f'Sections: {config.sections()}')  # Sections: ['moderator', 'admin', 'unknown']

要删除一个模块,只需使用remove_section()方法。

# Previous code in parser_playground.py
config.remove_section("unknown")
print(f'Sections: {config.sections()}')  # Sections: ['moderator', 'admin']

Python的ConfigParser对象提供了类似的操作选项的方法。例如,调用set()方法,不仅可以向模块添加新选项,还可以更新现有选项。同样,如果您想完全删除某个选项,请使用解析器的remove_option()方法。

# Previous code in parser_playground.py
config.set("admin""admin_page""false")
config.remove_option("admin""moderator_page")
print(f'Options in "admin" section: {config.items("admin")}')

处理完配置后,我们可以将其写回到相同或不同的文件,如下所示:

# Previous code in parser_playground.py
with open("config1.ini""w"as f:
    config.write(f)

插值

最后但也很重要的一点,让我们看一下使ConfigParser优于Python的json模块的东西:插值。插值意味着可以在调用某些get()方法返回值之前对其进行预处理。configparser模块提供两个插值类:BasicInterpolationExtendedInterpolation。第一个只允许重用配置文件中同一模块中的选项,并且其语句不如后一个类的语句漂亮。这就是为什么我们只用ExtendedInterpolation类。

以下代码段显示了使用Extended Interpolation语句的配置文件。

# interpolation_config.ini
[paths]
root_dir = /home/florian
downloads_dir = ${root_dir}/Downloads

[destinations]
app_dir = ${paths:downloads_dir}/application/python

本质上,第一个模块定义了根目录的路径。该路径用作第二个选项的前缀,即下载目录的路径。在第二个模块中,我们有一个选项app_dir,它重用了pahts模块中对downloads目录的定义。

为了掌握这一点,我们在实例化解析器时让 ConfigParser使用ExtendedInterpolation作为插值类型:

# interpolation.py
from configparser import ConfigParser
from configparser import ExtendedInterpolation

config = ConfigParser(interpolation=ExtendedInterpolation())
config.read("interpolation_config.ini")

如果现在打印destinations模块的app_dir选项的值,则会得到一个插值字符串。

# Previous code in interpolation.py
print(config.get("destinations""app_dir"))
$ python interpolation.py
/home/florian/Downloads/application/python

概要

本文不仅学习了如何使用初始化文件结构访问文件中的值,还学习了如何操作和扩展它们。此外,您还了解了configparser的插值功能以及如何根据需要使用它们。


往期推荐



5分钟完全掌握PyPy


5 分钟掌握 Python 中常见的配置文件


OpenCV人工智能图像识别技术实操案例


点击下方阅读原文加入社区会员




点赞鼓励一下

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/99095
 
576 次点击