configparser让python配置更简单
By 青衣极客 Blue Geek In 2019-12-16
经常训练机器学习模型或者部署项目程序的朋友,可能会被大量配置参数所困扰。看过一些项目的源码之后。大体上对于这些参数有这么几种处理办法:1. 直接以hard code写入程序,这当然是最基础的做法,但却会为后续更新升级带来很多麻烦;2. 从命令行输入中解析参数,这种方式对于少量的配置而言是非常不错的,但是如果参数有十个甚至数十个之多,那么就得祈祷使用者不会恶语相向了;3. 从文件载入配置参数,这种方式对于一些并不频繁变动的参数,特别对于大量的参数而言是非常合适的。在python中,少量参数可以使用argparse从命令行解析,大量参数可以使用configparser从文件读取。这也是很多python语言的开源代码常用的解决方案。接下来本文就对configparser的使用进行简单的介绍,为那些被大量参数苦扰的朋友提供一个简单易用的做法。
1. 不知道配置文件如何编写?
在使用配置文件设置参数的时候,常常会遇到一个问题,不同的处理模块对配置的格式要求差异较大,刚开始不知道配置文件如何编写。这种情况下,如果能使用该模块先生成一个默认的配置文件,然后再在这个默认配置文件的基础上修改就简单多了,对使用者而言也就没有什么门槛。我们先来看一看,python中的configparser模块是如何生成配置文件的。
from configparser import ConfigParser
config = ConfigParser()
# 添加第一个section
name_section = 'model'
config.add_section(name_section)
config.set(name_section, 'model_dir', 'model')
config.set(name_section, 'model_name', 'model.pth')
config.set(name_section, 'model_path', '%(model_dir)s/%(model_name)s')
# 添加第二个section
name_section = 'output'
config.add_section(name_section)
config.set(name_section, 'output_dir', 'output/')
config.set(name_section, 'prefix', 'demo')
# 添加第三个section
name_section = 'train'
config.add_section(name_section)
config.set(name_section, 'epoch', '100')
with open('../output/configparser.cfg', 'w') as wfid:
config.write(wfid)
# 展示生成文件的内容
!cat ../output/configparser.cfg
[model]
model_dir = model
model_name = model.pth
model_path = %(model_dir)s/%(model_name)s
[output]
output_dir = output/
prefix = demo
[train]
epoch = 100
从以上生成的配置文件可以看出,configparser处理的格式中,中括号用于定义一个section,每个section下使用“字段名 = value”的形式定义一个option。如果需要变动一些option的参数值,可以直接在文件中进行修改,也可以按照已有option的形式添加新的option。总体而言,得到默认配置文件之后,再修改配置是一个非常容易的事情。接下来就看看python如何从配置文件中读取参数。
2. 从文件读取配置
这里我们不修改默认的配置参数,只是展示读取配置文件的一般方法。
from configparser import ConfigParser
config = ConfigParser()
config.read('../output/configparser.cfg')
# 打印model_path
print(config.get('model', 'model_path'))
# 打印epoch
print(config.getint('train', 'epoch'))
model/model.pth
100
乍一看这个输出结果似乎没有什么特别的,符合预期,但这其中有些特殊点还是需要明了一下。在配置文件中,model_path的值并不是打印出来的这个值,而是”%(model_dir)s/%(model_name)s”。这样说来,确实是一个特殊点,那么怎么会出现这种情况呢?因为ConfigParser对象在解析配置文件时,将”%()s”形式的字符串进行了替换。这在一些具有关联性配置的地方尤其有用,既可以避免出现不一致,又可以保持较好的可读性,还可以节省代码输入的时间。
3. 三个配置模块怎样选?
事实上python中的configparser模块提供了三个类来进行配置文件的处理,分别是:ConfigParser、RawConfigParser以及SafeConfigParser。它们具体会有什么区别的?下面的演示将告诉你答案。
from configparser import RawConfigParser
config = RawConfigParser()
config.read('../output/configparser.cfg')
print(config.get('model', 'model_path'))
%(model_dir)s/%(model_name)s
从以上演示的输出结果可以看出,RawConfigParser在解析配置文件中的字段时,不会对”%()s”形式的字符串进行对应的替换,而是直接作为配置的值。在通常的配置时,解析参数的需求基本都不会是这样的。那么SafeConfigParser又有什么用呢?
from configparser import SafeConfigParser
config = SafeConfigParser()
config.read('../output/configparser.cfg')
print(config.get('model', 'model_path'))
model/model.pth
/usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:2: DeprecationWarning: The SafeConfigParser class has been renamed to ConfigParser in Python 3.2. This alias will be removed in future versions. Use ConfigParser directly instead.
从输出结果来看,SafeConfigParser与ConfigParser是一样的,而且python解释器还给出提示,从python3.2开始就将SafeConfigParser改名为ConfigParser,并且会在将来的版本中移除这个类。
那么在实际的使用中该如何来选择使用哪个类呢?这里建议使用ConfigParser。阅读完本文之后,应该就具备了在项目中使用configparser读取配置文件的方法,至少在参数调整和代码升级时不用那么痛苦。到此,关于python中configparser让配置更简单的话题就讨论完毕。

COMMENT
博客评论区功能由Github Issue提供,提交Issue时请以本文标题为话题。
"BG56-configparser让python配置更简单"