几乎所有的应用程序真正运行起来的时候都会有传入的参数,这些参数有时会通过一个或几个配置文件存储。
参数或配置文件的意义在于用户不需要修改程序代码,就可以改变应用程序的行为,让它更好地为应用服务。
比如 pytint
就带有一个参数 --rcfile
用以指定配罝文件,实现对定义代码风格的检测。
常见的配置文件格式有 .xml
和 .ini
等。
其中在MS Windows系统上 .ini
文件格式用得尤其多, 甚至操作系统的API也都提供了相关的接口函数来支持它。
类似 .ini
的文件格式在Linux 等操作系统中也是极常用的,比如 pylint 的配置文件就是这个格式。
Python 3中有个标准库来这种格式的文件读写与处理,名称为 configparser
。
ConfigParser
模块
在 Python 2 中这个模块名称为 ConfigParser
。
ConfigParser
的基本用法通过手册可以掌握,
但是仍然有几个知识点值得在这里跟大家说一下首先就是 getboolean()
这个函数。
getboolean()
根据一定的规则将配置项的值转换为布尔值,如以下的配置:
[sectioxil ]
optionl=0
当调用 getbooleanf('section1', 'opdoin1')
时,将返回 False
。不过 getboolean()
的真值规则值得一说:
除了 0
之外, no
、 false
和 off
都会被转义为 False
;
而对应的 1
、 yes
、 true
和 on
则都被转义为 True
, 其他值都会导致抛出 ValueError
异常。
这样的设计非常贴心,能够在不同的场合使用 yes/no
、 true/false
、 on/off
等更切合自然语言语法的词汇,
提升配置文件的可维护性。
除了 getboolean()
之外,还需要注意的是配置项的査找规则。
首先,在 ConfigParser
支持的配置文件格式里,有一个 [DEFAULT]
节,
当读取的配置项在不在指定的节里时, ConfigParser将会到 [DEFAULT]
节中査找。
举个例子,有如下配置文件:
cnt = '''[DEFAULT]
in_default = 'an option value in default'
[section]
addr = 'test'
'''
with open('xx_example.conf','w' ) as fo:
fo.write(cnt)
!cat xx_example.conf
[DEFAULT] in_default = 'an option value in default' [section] addr = 'test'
簡单地编写一段程序尝试通过 sectionl
获取 in default
的值 ()
。
import configparser
conf = configparser.ConfigParser ()
conf.read( 'xx_example.conf' )
conf.sections()
['section']
conf.get('section', 'addr')
"'test'"
可见ConfigParser
的行为跟上文描述是一致的。
不过,除此之外,还有一些机制导致 项目对配置项的査找更复杂,
这就是class ConfigParser
构造函数中的defaults
形参以及其 get(section, option[,raw[, vars]])
中的全名参数 vars()
。
如果把这些机制全部用上,那么配置项值的查找规则如下:
- 如果找不到节名,就抛出
NoSectionEnror
。 - 如果给定的配置项出现在
get()
方法的vars
参数中,则返回vars
参数中的值。 - 如果在指定的节中含有给定的配置项,则返回其值。
- 如果在
[DEFAULT]
中有指定的配置项,则返回其值。 - 如果在构造函数的defaults参数中有指定的配置项,则返回其值。
- 抛出
NoOptionError
。
因为篇幅所限,这里就不提供示例了,大家可以自行构造相应的例子来验证。 接下来要讲的是第三个特点。大家知道,在Python中字符串格式化可以使用以下语法:
'%(protocol)s ://%(server)s:%(port)s/' %{'protocol': 'http', 'server': 'example.com', 'port':1080}
'http ://example.com:1080/'
其实ConfigParSerS
持类似的用法,所以在配置文件中可以使用。有如下配a
选项:
$ cat format.conf
[DEFAULT]
conn_sti:= % (dbn) s://% (user) s: % (pw) s@% (host) s r % (port> s/% (db) s
dbn = mysql
user - root
host=localhost
port = 3306
[dbl]
user = aaa
pw=ppp
db=example
[db2]
host=192.168.0.110
pw=www
db=example
这是一个很常见的SQLAlchemy应用程序的配置文件,通过这个配置文件能够获取不同的数据库配置相应的连接字符串,
即 conn_str
。conn_str
定义在[DEFAULT]
中。但当它通过不同的节名来获取格式化后的值时,
根据不同配置,得到不同的值。先来看以下代码:
$ cat readformatini.py
import ConfigParser
conf = ConfigParser.ConfigParser ()
conf.read('format-conf ')
print( conf.get ( 'dbl ’ , ' conn_str ' ))
print( conf.get ('db2' ,'conn_str'))
以下是一个使用 ConfigParser
获取配置文件中 [db]
和 [db2]
两个节(section)配置的简单代码示例及输出说明:
$ python readformatini.py
mysql :ffa.aa: ppp@localhost: 3306/example
mysql ://root :www0192.16S . 0»110 : 3306/example
可以看到,当通过不同的节名调用 get()
方法时,格式化 conn_str
的参数是不同的,
这个规则跟上述查找配置项的规则相同。
with open('xx_db.ini', 'w') as fo:
fo.write('''
[mysql]
host=127.0.0.1
port=3306
user=root
password=yourpassword
dbname=test
[redis]
host=127.0.0.1
port=6379
password=88888
db=0
''')
配置文件由两部分组成 sections
与 items
,sections
用来区分不同的配置块,items
是 sections
下面的键值。
python3中提供了标准模块 configparser
,
该模块下有一个 ConfigParser
类,可以用来解析 ini
文件。
from configparser import ConfigParser
cf = ConfigParser()
cf.read('xx_db.ini')
['xx_db.ini']
程序输出结果:
print(cf.sections())
['mysql', 'redis']
输出mysql
下的所有配置项。
print(cf.options('mysql'))
['host', 'port', 'user', 'password', 'dbname']
输出mysql
下的所有键值对。
print(cf.items('mysql'))
[('host', '127.0.0.1'), ('port', '3306'), ('user', 'root'), ('password', 'yourpassword'), ('dbname', 'test')]
输出mysql
下配置项host
的值。
print(cf.get('mysql', 'host'))
127.0.0.1
输出port
。
print(cf.getint('mysql', 'port'))
3306
ConfigParser
的 get
方法可以根据 section
和 option
获取配置的值,
这个方法返回的是字符串,此外还提供了 getint
和 getfloat
方法,
分别获取 int
类型和 float
类型的配置项,如果嫌麻烦,可以统一使用 get
方法。
ConfigParser
也可以用来设置配置项,它提供了 add_section
方法和 set
方法,
但实际工作中都是手动配置 ini
文件,因此这部分内容可以不必关心。