1 configparser模块
用于生成
和修改
常见配置文档
,当前模块的名称在 python 3.x 版本中变更为 configparser。它提供类似于 Microsoft Windows INI
文件的结构。 ConfigParser允许编写可由最终用户轻松定制的 Python 程序。
配置文件由各部分组成
,后跟选项的键/值对
。 段名用[]
字符分隔。 这些键/值对
用:或=
隔开。 注释以#或;
开头。
1、如下,好多软件的常见配置文件:
首先说明几个概念:
- 下面的
[bitbucket.org]
用[]
包围起来的是section
,可以理解为节点 - 节点下面的是
键值对
,这个键就是option
然后再接着往下看就会明白section和option这个概念了!
注意:
DEFAULT
这个关键字不属于section
!我也不太明白
[DEFAULT] # 节点section DEFAULT
# 下面是该节点对应所有键(option)/值对信息
serveraliveinterval = 45
compression = yes
compressionlevel = 9
forwardx11 = yes
[bitbucket.org] # 节点section bitbucket.org
# 下面是该节点对应所有键/值对信息
user = hg
[topsecret.server.com] # 节点 section topsecret.server.com
# 下面是该节点对应所有键/值对信息
host port = 50022
forwardx11 = no
2、使用configparser模块生成上面的配置文件
import configparser
config = configparser.ConfigParser()
# DEFALULT 就相当于时一个字典的key
# 对应的value还是一个字典,相当于时一个嵌套字典
config["DEFAULT"] = {
'ServerAliveInterval': '45',
'Compression': 'yes',
'CompressionLevel': '9'}
config['bitbucket.org'] = {
}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {
}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022' # mutates the parser
topsecret['ForwardX11'] = 'no' # same here
config['DEFAULT']['ForwardX11'] = 'yes'
with open('config.ini', 'w') as configfile:
config.write(configfile)
生成config.ini
结果如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qqCtrHR1-1646310028648)(./imgs/cp1.png)]
3、读取配置文件
import configparser
def read_config():
# 1 读取解析 .ini配置文件
config = configparser.ConfigParser()
# .ini配置文件中添加的有中文注释,因此需要utf-8编码读取,否则会报错
config.read('config.ini', encoding='utf-8')
# 2 sections() 读取所有部分,以列表的形式返回所有节点信息
sections = config.sections()
# 节点 [DEFAULT] 并没有读取到列表,不清楚为什么
print(sections) # ['bitbucket.org', 'topsecret.server.com']
# 3 获取指定节点的所有配置信息,以列表的形式返回某个节点及其之前的所有配置信息,如果该节点与前面的节点有相同的key则覆盖
items1 = config.items('DEFAULT')
items2 = config.items('bitbucket.org')
items3 = config.items('topsecret.server.com')
print(items1)
# [('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('forwardx11', 'yes')]
print(items2)
# [('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('forwardx11', 'yes'), ('user', 'hg')]
print(items3)
# [('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('forwardx11', 'no'), ('host port', '50022')]
# 注意观察,[topsecret.server.com] 节点下 ('forwardx11', 'no') 会覆盖之前的配置,如果有相同的key,后面的key值会覆盖前面的key值,和添加字典一样!
# 4 获取指定节点下指定的options值,返回节点下所有key值的列表
# keys1 = config.options('DEFAULT') # DEFAULT 并不属于sections,感觉这个应该是一个比较特殊的关键字,不解析
# configparser.NoSectionError: No section: 'DEFAULT'
keys2 = config.options('bitbucket.org')
keys3 = config.options('topsecret.server.com')
# 然后把DEFALUT的key追加到每个节点的后面
print(keys2) # ['user', 'serveraliveinterval', 'compression', 'compressionlevel', 'forwardx11']
print(keys3) # ['host port', 'forwardx11', 'serveraliveinterval', 'compression', 'compressionlevel']
# 5、获取指定节点下指定的option值,就是获取指定节点下key对应的值
'''
ConfigParserObject.get(section, option)
返回结果是字符串类型
ConfigParserObject.getint(section, option)
返回结果是int类型
ConfigParserObject.getboolean(section, option)
返回结果是bool类型
ConfigParserObject.getfloat(section, option)
返回结果是float类型
'''
user = config.get('bitbucket.org', 'user')
print(user, type(user)) # hg <class 'str'>
interval = config.get('DEFAULT', 'serveraliveinterval')
print(interval, type(interval)) # 45 <class 'str'>
interval2 = config.getint('DEFAULT', 'serveraliveinterval')
print(interval2, type(interval2)) # 45 <class 'int'>
# 5 检查section(节点) 或 option(键值)是否存在
# 如果存在返回True,否则返回False
# 检查section是否存在
res1 = config.has_section('DEFAULT')
res2 = config.has_section('bitbucket.org')
print(res1, res2) # False True
# 检查option是否存在
res3 = config.has_option('DEFAULT', 'forwardx11')
res4 = config.has_option('bitbucket.org', 'user')
print(res3, res4) # True True
# 可以看出DEFAULT 不属于section节点,但是DEFAULT又可以作为section获取下面的key,疑惑!
if __name__ == '__main__':
# write_config()
read_config()
>>> import configparser
>>> config = configparser.ConfigParser()
>>> config.sections()
[]
>>> config.read('example.ini')
['example.ini']
>>> config.sections()
['bitbucket.org', 'topsecret.server.com']
>>> 'bitbucket.org' in config
True
>>> 'bytebong.com' in config
False
>>> config['bitbucket.org']['User']
'hg'
>>> config['DEFAULT']['Compression']
'yes'
>>> topsecret = config['topsecret.server.com']
>>> topsecret['ForwardX11']
'no'
>>> topsecret['Port']
'50022'
>>> for key in config['bitbucket.org']: print(key)
...
user
compressionlevel
serveraliveinterval
compression
forwardx11
>>> config['bitbucket.org']['ForwardX11']
'yes'
3、configparser的增删改查语法
import ConfigParser
config = ConfigParser.ConfigParser()
config.read('i.cfg')
# ########## 读 ##########
#secs = config.sections()
#print secs
#options = config.options('group2')
#print options
#item_list = config.items('group2')
#print item_list
#val = config.get('group1','key')
#val = config.getint('group1','key')
# ########## 改写 ##########
#sec = config.remove_section('group1')
#config.write(open('i.cfg', "w"))
#sec = config.has_section('wupeiqi')
#sec = config.add_section('wupeiqi')
#config.write(open('i.cfg', "w"))
#config.set('group2','k1',11111)
#config.write(open('i.cfg', "w"))
#config.remove_option('group2','age')
#config.write(open('i.cfg', "w"))
参考:https://www.jianshu.com/p/417738fc9960
参考:https://geek-docs.com/python/python-tutorial/python-configparser.html
参考:https://docs.python.org/3/library/configparser.html
2 PyYAML模块
1、PyYAML模块安装
pip install PyYAML
2、yaml文件的语法格式参考
- 参考:https://www.runoob.com/w3cnote/yaml-intro.html
- 参考:http://www.ruanyifeng.com/blog/2016/07/yaml.html
3、yaml使用
- 参考:https://shliang.blog.csdn.net/article/details/111591030
- 参考:https://geek-docs.com/python/python-tutorial/python-yaml.html
2.2 yaml基本使用
在yolov5
中就是通过yaml文件
来配置模型的定义:
参考:https://github.com/ultralytics/yolov5/blob/c72270c076e1f087d3eb0b1ef3fb7ab55fe794ba/models/yolo.py
2.2.1 使用yaml.load()读取yaml文件,并获取其中的配置信息
1、首先有一个配置文件config.yaml
,内容如下:
optimizer:
- SGD
- Adam
train:
optimization: Adam
learning_rate: 0.001
batch_size: 64
epoch: 200
2、读取yaml文件
data_dict = yaml.load(f, Loader=yaml.FullLoader)
:把yaml文件解析成字典- 使用字典的key获取对应的值
import yaml
def read_yaml():
yaml_f = open('./config.yaml', 'r', encoding='utf-8')
data_dict = yaml.load(yaml_f, Loader=yaml.FullLoader)
print(type(data_dict))
print(data_dict)
# {'optimizer': ['SGD', 'Adam'], 'train': {'optimization': 'Adam', 'learning_rate': 0.001, 'batch_size': 64, 'epoch': 200}}
# 因为yaml文件被解析成字典的形式了,因此就可以通过字典的形式进行访问对应的值了
lr = data_dict['train']['learning_rate']
print(lr, type(lr)) # 0.001 <class 'float'>
if __name__ == '__main__':
read_yaml()
2.2.2 使用yaml.load_all()读取多个yaml文档
1、使用配置文件docs.yaml如下:
我们在docs.yaml中有两个文档
。 文件用---
分隔。(---
加不加都是一样的,只是方便区分而已)
cities:
- Bratislava
- Kosice
- Trnava
- Moldava
- Trencin
---
companies:
- Eset
- Slovnaft
- Duslo Sala
- Matador Puchov
2、读取多个yaml文档
docs_generator = yaml.load_all(yaml_f, Loader=yaml.FullLoader)
:读取得到的是一个迭代器- 迭代器中存储的是一个一个的字典数据,可以循环遍历获取
import yaml
def read_docs_yaml():
yaml_f = open('./docs.yaml', 'r', encoding='utf-8')
# 读取的是一个迭代器
docs_generator = yaml.load_all(yaml_f, Loader=yaml.FullLoader)
print(type(docs_generator)) # <class 'generator'>
print(docs_generator) # <generator object load_all at 0x000001C0F2D51200>
# 迭代器中存储的就是两个字典
# docs_list = list(docs_generator)
# print(docs_list)
# [{'cities': ['Bratislava', 'Kosice', 'Trnava', 'Moldava', 'Trencin']}, {'companies': ['Eset', 'Slovnaft', 'Duslo Sala', 'Matador Puchov']}]
for doc in docs_generator:
for key, value in doc.items():
print(key, '->', value)
# cities -> ['Bratislava', 'Kosice', 'Trnava', 'Moldava', 'Trencin']
# companies -> ['Eset', 'Slovnaft', 'Duslo Sala', 'Matador Puchov']
if __name__ == '__main__':
read_docs_yaml()
2.2.3 把数据序列化成yaml格式,并写入到yaml文件
1、如下,把数据写入到yaml文件中
import yaml
def write_yaml():
users = [{
'name': 'John Doe', 'occupation': 'gardener'},
{
'name': 'Lucy Black', 'occupation': 'teacher'}]
data_str = yaml.dump(users)
print(type(data_str)) # <class 'str'>
print(data_str)
'''
- name: John Doe
occupation: gardener
- name: Lucy Black
occupation: teacher
'''
with open('users.yaml', 'w') as f:
# dump() 第一个参数是数据,第二个参数是文件对象
data = yaml.dump(users, f)
if __name__ == '__main__':
write_yaml()
生成users.yaml文件内容如下:
- name: John Doe
occupation: gardener
- name: Lucy Black
occupation: teacher
2、示例2
import yaml
def write_yaml2():
train_config = {
'optimizer':['SGD', 'Adam'],
'train':{
'optimization': 'Adam',
'learning_rate': 0.001,
'batch_size': 64,
'epoch': 200}}
with open('train_config.yaml', 'w') as f:
data = yaml.dump(train_config, f)
if __name__ == '__main__':
write_yaml2()
生成train_config.yaml文件内容如下:
optimizer:
- SGD
- Adam
train:
batch_size: 64
epoch: 200
learning_rate: 0.001
optimization: Adam
2.2.4 读取yaml文件,并对键值进行排序
1、items.yaml文件内容为:
raincoat: 1
coins: 5
books: 23
spectacles: 2
chairs: 12
pens: 6
`
2、对读取的yaml内容按照key进行排序
import yaml
def read_yaml_sorted_key():
with open('items.yaml', 'r') as f:
data_dict = yaml.load(f, Loader=yaml.FullLoader)
print(type(data_dict)) # <class 'dict'>
print(data_dict)
# {'raincoat': 1, 'coins': 5, 'books': 23, 'spectacles': 2, 'chairs': 12, 'pens': 6}
sorted = yaml.dump(data_dict, sort_keys=True)
print(type(sorted)) # <class 'str'>
print(sorted)
'''
books: 23
chairs: 12
coins: 5
pens: 6
raincoat: 1
spectacles: 2
'''
# 你也可以把排序后的配置写到一个新的文件中
with open('items_new.yaml', 'w') as f2:
yaml.dump(data_dict, f2, sort_keys=True)
if __name__ == '__main__':
read_yaml_sorted_key()