配置文件很简单:Python 的 configparser 模块 配置文件很简单:Python 的 configparser 模块

配置文件很简单:Python 的 configparser 模块

Python Logo正如你可能从这周末的第二篇 Python 文章中看出的那样,我一直在做一些 Python 编程,无论是在工作中还是在家里。Python 是一种非常容易上手的语言,它的一大优势在于其“开箱即用”的设计理念。

在其他语言中,下载和安装附加模块非常普遍——例如 Perl 的 CPAN 或 PHP 的 Pear,当然,Go 语言几乎从一开始就是为使用 GitHub 而设计的。Python 也拥有一个强大的附加模块社区(参见 pip),但它本身也包含了大量开箱即用的功能。回顾脚本语言的发展历程,Perl 和 TCL 的库相对较少。Python 之后,许多语言在库的构建方面采取了更为全面的策略。

在今天的教程中,我们将学习 Python 的“configparser”模块。这个模块的妙处在于,你再也不用手动编写配置文件解析逻辑了。希望你现在编写的代码不多,并且使用的是 YAML、JSON 或者(想想都可怕)XML 之类的格式。如果不是,或者你想要更简单的方案,你一定会爱上 configparser。

configparser 可以处理 .ini 文件。我们来看一个示例:

 [服务器]
最大待处理文件数 = 12
输入目录 = /tmp/input
输出目录 = /tmp/output

[日志记录]
日志目录 = /tmp/log
调试 = 否

我已将此文件保存为“leb.ini”。该配置文件包含两个“部分”(服务器和日志记录),每个部分下又包含若干配置项。

让我们来分析一下这个庞然大物!

 #!/usr/bin/python3

导入 configparser
config = configparser.ConfigParser()
config.read('leb.ini')
for section in config.sections():
    print("找到配置部分:%s" % (section))

wants_debug = config['logging'].getboolean("Debug")
如果 wants_debug:
    print("这是调试输出")
别的:
    print("调试未开启")
print("我正在处理来自 %s 的最多 %d 个文件" % ( 
    config["服务器"].getint("MaxFilesToProcess"), 
    配置 ["服务器"]["输入目录"]))
如果 'notify_address' 在 config['logging'].keys() 中:
    print("通知已配置")
别的:
    print("通知未配置")

我把几行长字换行了,这样更容易阅读。

运行此脚本后,会产生以下输出:

# ./server.py 
找到配置部分:服务器
找到配置部分:日志记录
调试模式未开启
我最多正在处理来自 /tmp/input 目录的 12 个文件
通知未配置

让我们来逐段分析代码。首先,我们导入 configparser,创建一个名为 config 的 ConfigParser 对象,然后让它读取我们的 leb.ini 文件。

`config.sections()` 会返回“server”和“logging”这两个配置段。请注意,在 .ini 文件中,所有内容都必须位于一个配置段内。配置项不能“裸露”。如果您的配置很简单,当然可以只有一个配置段,但至少必须有一个。

现在我们开始引用这些配置项。请注意,它们以字符串形式存储,因此如果我引用 `config["logging"]["Debug"]`,我会得到字符串“no”,这正是我在 `.ini` 文件中设置的值。但我真正需要的是一个布尔值(True 或 False)。为了获得该值,我使用了 `getboolean()` 方法,它可以正确识别 `yes/no`、`on/off`、`true/false` 和 `1/0`。

我还使用 `getint()` 函数将配置项获取为整数(或使用 `getfloat()` 函数获取为浮点数)。当然,您也可以这样做:

 int(config["server"]["MaxFilesToProcess"])

如果 MaxFilesToProcess 不是 int 类型,并且您尝试使用 getint() 或 int() 强制转换,Python 将引发 ValueError(正如您可能预期的那样)。

最后,我们如何查看配置项是否存在?我们的配置变量只是一个字典,因此我们可以使用典型的 Python 字典操作,例如测试 'notify_address' 是否是 config['logging'].keys() 中的一个键。