正如你可能从这周末的第二篇 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() 中的一个键。