configparser模块的高级用法

2019年7月7日 / 68次阅读 / Last Modified 2019年7月7日
configparser模块

上一篇《用configparser模块读写ini配置文件》,主要聚焦在读写配置文件的基本方法。本文介绍configparser模块的一些高级用法。

首先,我觉得要清楚一个概念,配置文件不一定都有ini后缀,这只是Win系统的习惯。Win系统的文件,一般都通过后缀名来区分文件类型。Linux系统下,文件有没有后缀是无所谓的。只要是文本文件,都可以用作配置文件。

更多读取配置的方式

configparser模块除了使用read函数读取配置文件以外,还可以从字符串,dict对象读取配置。下面是示例代码:

>>> configstr = """
... [Server]
... addr = 1.2.3.4
... domain = py.maixj.net
... [MISC]
... port = 12345
... log = on
... """
>>> config = configparser.ConfigParser()
>>> config.read_string(configstr)
>>> config.sections()
['Server', 'MISC']

下面是从dict对象读取配置的示例代码:

>>> config_dict = {'Server':{'addr' : '1.2.3.4',
...                          'domain' : 'py.maixj.net'},
...                'MISC' : {'port' : 12345,
...                          'log' : 'on'}}
>>> config = configparser.ConfigParser()
>>> config.read_dict(config_dict)
>>> config.sections()
['Server', 'MISC']
>>> config['MISC'].getboolean('log')
True

建议保持配置项小写

在使用configparser模块时,始终要意识到这个细节。为了保持简单,我们都使用小写即可,除了section的名称

下面的代码,判断log是否在MISC这section内,不管log这三个字母如何大小写变化,结果都是True:

>>> 'log' in config['MISC']
True
>>> 'LOG' in config['MISC']
True
>>> 'loG' in config['MISC']
True

DEFAULT区域无法删除

我们先看一下clear函数的用法:

>>> config_str = """
... [DEFAULT]
... name = maixj
... gender = male
... [Server]
... addr = 1.2.3.4
... domain = py.maixj.net
... [MISC]
... log = off
... """
>>> config = configparser.ConfigParser()
>>> config.read_string(config_str)
>>> config['MISC'].getboolean('log')
False
>>> config['MISC'].clear()
>>> config['MISC'].getboolean('log') is None
True

在section下调用clear函数,就是讲section下所有的配置项清除。如果在整个config模块下调用clear,就是将所有的section清除,除了DEFAULT区域:

>>> config.sections()
['Server', 'MISC']
>>> config['Server']['domain']
'py.maixj.net'
>>> config['Server'].clear()
>>> config['Server'].get('addr') is None
True
>>> config.clear()
>>> config.sections()
[]
>>> config['DEFAULT']['name']
'maixj'
>>> config['DEFAULT']['gender']
'male'
>>> config.default_section
'DEFAULT'
>>> config.defaults()
OrderedDict([('name', 'maixj'), ('gender', 'male')])

sections函数看不到任何区域了,但是DEFAULT区域还在。

遍历某区域的所有配置

除了上一篇介绍的方法,这里再给出另一种遍历的方法,使用items函数(dict对象也有这个函数):

>>> config_str = """
... [Server]
... addr = 1.2.3.4
... domain = py.maixj.net
... log = yes
... cache = yes
... """
>>> config = configparser.ConfigParser()
>>> config.read_string(config_str)
>>> for k,v in config['Server'].items():
...     print(k,'=',v)
...
addr = 1.2.3.4
domain = py.maixj.net
log = yes
cache = yes

配置值的插入替换(interpolation)

之前所有的代码使用中,创建config对象的方法都是一样的,这种方式支持基本的配置值插入替换(basic interpolation):

>>> config_str = """
... [Path]
... home = /home/xinlin
... video = %(home)s/Video
... movie = %(video)s/Movie
... """
>>> config = configparser.ConfigParser()
>>> config.read_string(config_str)
>>> config['Path']['home']
'/home/xinlin'
>>> config['Path']['video']
'/home/xinlin/Video'
>>> config['Path']['movie']
'/home/xinlin/Video/Movie'

Basic Initerpolation的意思是,这种插入替换只能出现在相同的区域,不能跨区,正如上面的代码,home与video,audio在同一个Path区域。插入替换home值的方式是:%(home)s

还有个细节,上面的代码,实现的是多层插入替换,movie的值来之video,video的值又来自home。我看configparser模块的源码,貌似支持10层这样的插入替换。

configparser模块还支持扩展的配置值插入替换方式,Extended Interpolation。扩展的方式,就是在替换的时候,可以跨区,而且语法上也有区别。Basic和Extended两种方式的语法不兼容。下面是Extended Interpolation的代码示例:

>>> config_str = """
... [Home]
... home = /home/xinlin
... [Lib]
... lib = ${Home:home}/Lib
... gcc_lib = ${lib}/gcc
... [DEFAULT]
... binpath = /usr/bin
... [Path]
... path = ${binpath}/secret
... """
>>> from configparser import ConfigParser, ExtendedInterpolation
>>> config = ConfigParser(interpolation=ExtendedInterpolation())
>>> config.read_string(config_str)
>>> config['Lib']['lib']
'/home/xinlin/Lib'
>>> config['Lib']['gcc_lib']
'/home/xinlin/Lib/gcc'
>>> config['Path']['path']
'/usr/bin/secret'

注意config对象的创建方式变了,多了一个参数。Extended Interpolation方式的插入替换语法是 ${section:option},如果此语法中没有section,要么在同section下找,要么在DEFAULT区域下找

有了插入替换,使用configparser可以创建出满足各种需求场景的配置文件。

允许配置没有值(allow_no_value)

如果某个配置项,后面有=号,或者:号,表示值为空字符串,并不是没有值。不写=号,或者:号,才是没有值。没有值,就是None,就像没有此配置项一样。请看下面的示例代码:

>>> config_str = """
... [ABC]
... a = 1
... b
... c = 3
... """
>>> config = configparser.ConfigParser(allow_no_value=True)
>>> config.read_string(config_str)
>>> config['ABC']['b']
>>> config['ABC']['b'] is None
True

configparser模块还有一些高级特性,不过用的不多,有兴趣可继续阅读官方教材:https://docs.python.org/3/library/configparser.html

-- EOF --

本文链接:https://www.pynote.net/archives/556

留言区

电子邮件地址不会被公开。 必填项已用*标注


前一篇:
后一篇:

More

麦新杰的Python笔记

Ctrl+D 收藏本页


©Copyright 麦新杰 Since 2019 Python笔记

go to top