网罗几种中Python配置文件方式,总有一款适合你

提起Python的的配置文件,估计你去问10个人,每个人给你的答案多多少少都不一样,原因就是轮子太多了,并没有一个足够好到让大家普遍都接收的,所以在不适合场景的情况下,造轮子, 今天跟大家聊聊常用的集中配置方式。

configparser or ConfigParser

configparser or ConfigParser

configpare算是老牌的配置文件选择之一了,优点是标准库,不需要安装,但是需要注意的一点是,在Python2和Python3上使用方式略有差异

是否是标准库

标准库,Python2上和Python3上包名称有差异 不需要额外安装模块算是优点之一

python2中包名称首字母大写

python2文档[1]

>>> import sys>>> sys.version'2.7.10 (default, Feb 22 2019, 21:55:15) \n[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.37.14)]'>>>>>>>>> import ConfigParser>>> config = ConfigParser.ConfigParser()>>> config.readfp(open('example.ini'))>>> config.get('topsecret.server.com', 'Port')'50022'>>>>>> config.get('topsecret.server.com', 'ForwardX11')'no'>>>
python3中包名称首字母小写

python3文档[2]

>>> import sys>>> sys.version'3.7.2 (default, Feb 24 2020, 13:04:30) \n[Clang 10.0.1 (clang-1001.0.46.4)]'>>>>>>>>> import configparser>>> config = configparser.ConfigParser()>>> config.readfp(open('example.ini'))/Users/admin/.pyenv/versions/3.7.2/bin/bpython:1: DeprecationWarning: This method will be removed in future versions.  Use 'parser.read_file()' instead.  #!/Users/admin/.pyenv/versions/3.7.2/Python.framework/Versions/3.7/bin/python>>>>>> config.get('topsecret.server.com', 'Port')'50022'>>>

pyyaml

随着yaml文件的普及,不少项目开始把自己的配置文件换成了yaml文件格式

是否是标准库

非标准库,需要单独安装,另外需要注意的是,yaml编写格式对齐有要求,一定要特别注意,常见的使用的有gitlab-ci的配置文件,k8s的配置文件等,还是比较普及的。

pyyaml[3]

安装

pip install pyyaml

演示

python2
>>> import yaml>>>>>>>>> config = yaml.safe_load(open('example.yaml'))>>> config{'name': 'zhuima', 'address': 'beijing'}>>>>>>>>> import sys>>> sys.version'2.7.10 (default, Feb 22 2019, 21:55:15) \n[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.37.14)]'>>>
python3
>>> import yaml>>> config = yaml.safe_load(open('example.yaml'))>>> config{'name': 'zhuima', 'address': 'beijing'}>>>>>> import sys>>> sys.version'3.7.2 (default, Feb 24 2020, 13:04:30) \n[Clang 10.0.1 (clang-1001.0.46.4)]'>>>

json

说到yaml, 不得不说的那就是json,其实这个应该是写在yaml之前的,但是我个人觉得,这个可读性确实有点差,编辑的时候经常会出问题,所以就放在了后面

是否是标准库

标准库,无需单独安装,编辑的时候需要特别注意,避免语法错误

大家在看别人的代码的时候,可能会看到simplejson这个库,原因有几个:

•json是在python2.6的时候引入的,simplejson可以兼容更低版本的Python•simplejson比json块,最快的是cjson

json模块对比扩展阅读,文档很老了[4]

辅助工具

在线校验json[5]

simplejson[6]

演示

>>> import json>>>>>> with open('example.json') as fp:...     data = json.load(fp)......>>> >>> data{u'name': u'zhuima', u'address': u'beijing'}>>> data.get('name')u'zhuima'>>>>>> sys.version'2.7.10 (default, Feb 22 2019, 21:55:15) \n[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.37.14)]'>>>
python3
>>> import json>>>>>>>>> with open('example.json') as fp:...     data = json.load(fp)......>>> data{'name': 'zhuima', 'address': 'beijing'}>>> data.get('address')'beijing'>>> import sys>>>>>> sys.version'3.7.2 (default, Feb 24 2020, 13:04:30) \n[Clang 10.0.1 (clang-1001.0.46.4>>> from dotenv import load_dotenv>>>

python-dotenv

这个是我用的最多的,也是比较喜欢的一个模块,足够简单,配置就是键值对。

是否是标准库

非标准库,需要单独安装,不过支持比较广,对应的Flask, Django都有对应的包,仓库的地址

python-dotenv对应github仓库[7]

安装

pip install python-dotenv

演示

python2
>>> from dotenv import load_dotenv>>> import os>>>>>>>>> ROOT = os.path.join(os.path.dirname('__file__'), '.')>>>>>> dotenv_path = os.path.join(ROOT, '.env')>>>>>>>>> load_dotenv(dotenv_path)True>>>>>> os.getenv('name')'zhuima'>>> os.getenv('address')'beijing'>>>>>>>>> import sys>>> sys.version'2.7.10 (default, Feb 22 2019, 21:55:15) \n[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.37.14)]'>>>
python3
>>> from dotenv import load_dotenv>>>>>>>>> import os, pathlib>>>>>> dotenv_path = pathlib.Path('.') / '.env'>>> dotenv_pathPosixPath('.env')>>> load_dotenv(dotenv_path...... )True>>>>>> os.getenv('name')'zhuima'>>>>>> os.getenv('address')'beijing'>>>>>> import sys>>> sys.version'3.7.2 (default, Feb 24 2020, 13:04:30) \n[Clang 10.0.1 (clang-1001.0.46.4)]'>>>

纯py文件(常量)

有的时候为了简单,或者说是省事,就把需要的常量定义到一个文件里,使用起来直接导入对应的包即可

演示

python2
>>> import example_consts>>> example_consts.ADDRESS'beijing'>>>>>> example_consts.NAME'zhuima'>>>>>> import sys>>> sys.version'2.7.10 (default, Feb 22 2019, 21:55:15) \n[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.37.14)]'>>>
python3
>>> import example_consts>>> example_consts.ADDRESS'beijing'>>>>>>>>> example_consts.NAME'zhuima'>>>>>>>>> import sys>>> sys.version'3.7.2 (default, Feb 24 2020, 13:04:30) \n[Clang 10.0.1 (clang-1001.0.46.4)]'>>>

类Django配置

工程化的时候,是需要区分环境的,不同的环境连接DB和中间件的地址或部分常量是有所差异的,这个时候就需要以环境区分来进行加载操作,一般是在入口文件里定义一个变量,启动时去读取这个变量,如果存在就按照指定环境的配置启动,如果没有显示定义,就按默认配置启动。

更多内容可以参考李辉大大的文档[8]

演示

定义配置文件
# vim configmap.pyclass Config():      AUTHOR='zhuima'class DevelopmentConfig(Config):   DEBUG = True   SQL_URI='url'class TestConfig(Config):   SQL_URI='url'class ProductionConfig(Config):   SQL_URI='url'config ={    'dev':DevelopmentConfig,   'test':TestConfig,   'product':ProductionConfig,   'default':DevelopmentConfig}
引用配置文件
from configmap import *## 方式一app.config.from_object(ProductionConfig)## 方式二app.config.from_object(config['product'])

总结

真的,写文档的时候真的是很难开头,因为甭管怎么写,都会被喷的,这方面的轮子实在是太多太多了,就不再一一演示了,有些场景下,但凡用着不爽,一个新的轮子就出来了,但是很多时候真的是不存在普适性,有大佬感兴趣的话,可以来一发,哈哈。