之前写了一篇关于《Python深度学习项目代码结构》的文章:
2022-12-07
主要介绍了在构建项目的时候,把架构布置清晰。里面提到了configs模块,用来配置超参数、文件路径、普通参数、常量、标志等。
参数太多和项目架构太大的时候,多次修改找它们可能会消耗很多时间,同时无法突出项目核心部分,能不能有效的管理它们?
1、如果项目仅仅使用了python语言开发,可以写在py文件中,例如settings.py或者config.py,在需要的地方import导入调用即可,也很方便。弊端是,项目往往不仅仅用python语言,还可能Java、c++、go/rust等,就无法跨语言共享参数了。
2、常见的还有保存在 ini、cfg、json、toml、yaml、properties 等文件下。
将参数分开放,不仅仅提高效率,项目核心代码也会显得整洁。
下面是几种常见方法的介绍:
Part1ini和cfg文件
ini和cfg文件的写法比较简单,通常由三部分组成:节(Section)、键(key)和值(value),使用Python 内置库 configparser就可以解析配置文件。假如我们的配置文件是config.cfg,内容如下:
[GENERAL]
domains = tourism
seed = 20230301
[logging]
usecolor = False
screen_level = results
file_level = results
file = auto
我们写个代码读取
from configparser import ConfigParser
def load_config(config_file):
"""
加载config file到 ConfigParser()
:param config_file: path to config
:type config_file: str
"""
global config
config = None
if config_file is not None:
print('load config_file')
try:
config = ConfigParser()
config.read(config_file)
except Exception as inst:
print('Failed to parse file', inst)
else:
print('load empty config')
config = ConfigParser()
return config
if __name__ == '__main__':
cfg = load_config(config_file='configs.ini')
print(cfg.items("GENERAL"))
# [('domains', 'tourism'), ('seed', '20230301')]
print(cfg_dict := dict(cfg.items("GENERAL")))
# {'domains': 'tourism', 'seed': '20230301'}
configparser 默认将值以字符串的形式呈现,在cfg或ini文件中都不需要再加双引号了,这里我们还使用了海象符号:=将读取的配置文件转换成字典,方便调用。
Part2json配置文件
上面我们读取cfg文件后最后转换成字典,我们python内置了json不是可以处理字符串和字典吗?
json.load() 用于从文件中读取 JSON 文档
json.loads() 用于将JSON字符串文档转换为Python字典。
我们将上面的配置转换成json格式:
然后读取:
import json
with open('configs.json') as j:
cfg = json.load(j)['logging']
print(cfg)
# {'file': 'auto', 'file_level': 'results', 'screen_level': 'results'}
也实现了文件配置,缺点是无法写注释、无法写过长或复杂的参数配置,容易出错。
我们再看看有没有其他方案:
Part3yaml
yaml(yml)[1]格式是目前较为流行的一种配置文件,但上手不如前面的cfg/json等方式那么容易。最近写的Rasa对话机器人相关配置、docker_compose.yml等都是使用的yaml文件。
python相关的yaml工具包:https://yaml.readthedocs.io/en/latest/ https://pyyaml.org/ https://hitchdev.com/strictyaml/
首先我们要下载一下PyYAML依赖包:
pip install pyyaml
我们的配置内容在yaml文件中是这样的:
使用yaml的时候,我们不使用load()去加载,而是使用safe_load(),这样去加载即可:
import yaml
from pprint import pprint
with open("config.yaml", "r") as config:
cfg = yaml.safe_load(config)
pprint(cfg)
# output:
{'GENERAL': {'domains': 'tourism', 'seed': 20230301},
'logging': {'file': 'auto',
'file_level': 'results',
'screen_level': 'results'}}
工作中也使用yaml文件来配置,这里总结了一点yaml文件的配置规则,更多内容还需要同学们从官方文件了解哦:
1yaml文件规则
-
区分大小写; -
使用缩进表示层级关系; -
使用空格键缩进,而非Tab键缩进 -
缩进的空格数目不固定,只需要相同层级的元素左侧对齐; -
文件中的字符串不需要使用引号标注,但若字符串包含有特殊字符则需用引号标注; -
注释标识为#
2yaml文件数据结构
-
对象:键值对的集合 -
键值对用冒号 “:” 结构表示,冒号与值之间需用空格分隔 -
数组:一组按序排列的值(简称 "序列或列表") -
数组前加有 “-” 符号,符号与值之间需用空格分隔 -
纯量(scalars):单个的、不可再分的值(如:字符串、bool值、整数、浮点数、时间、日期、null等) -
None值可用null和~ 表示
从上面可以看出yaml文件数据结构中,字典、列表和数值等的组合吗?确实是的,我们构造好了字典映射后,都可以自动化yaml.dump()到yaml文件中。
以上就是关于python项目中关于配置文件的讲解了,像toml和xml等配置这里就不赘述了,大家感兴趣可以自行搜索学习。还有使用argpase等模块指定参数和值的方式会再讨论。由于作者水平有限,未尽之处还请指教。
参考资料
yaml.org: "https://yaml.org/"
2023-02-27
2023-02-27
2023-02-27
2023-02-02
2023-01-14
“点赞”是喜欢,“在看、分享”是真爱
<