目录
1.通过配置文件生成 config
2.Config.fromfile 实现
1.-知乎推荐
Config 主要是提供各种格式的配置文件解析功能,包括 py、json、ymal 和 yml,是一个非常基础常用类,对该类的熟练使用和具体实现深入理解,有助于灵活使用 OpenMMLab 系列框架。Config 类用于解析 OpenMMLab 开源框架的各种格式配置文件,不仅如此还实现了很多方便使用的 API,例如配置读写、配置打印、配置合并等等功能
该功能最为常用,配置文件可以是 py、yaml、yml 和 json 格式。
cfg = Config.fromfile('tests/data/config/a.py')
cfg.filename
cfg.item4 # 'test'
cfg # 打印 config path,和字典内容...
Config.fromfile
是 Confi
g 类中应用最为广泛的函数,有必要对其实现进行分析。其最上层大致逻辑是:
def fromfile(filename,
use_predefined_variables=True,
import_custom_modules=True):
# 对文件进行解析,返回字典和文本内容,其中文本内容就是文件中的原始未解析前内容
cfg_dict, cfg_text = Config._file2dict(filename,
use_predefined_variables)
# 如果需要进行定制化导入,则对模块进行导入
if import_custom_modules and cfg_dict.get('custom_imports', None):
import_modules_from_strings(**cfg_dict['custom_imports'])
# 生成 Config 对象,返回
return Config(cfg_dict, cfg_text=cfg_text, filename=filename)
几乎所有复杂操作都在 Config._file2dict
中。要特别注意 cfg_text
到底是啥?假设配置文件是 retinanet_r50_fpn_1x_coco.py
,其内容是:
_base_ = [
'../_base_/models/retinanet_r50_fpn.py',
'../_base_/datasets/coco_detection.py',
'../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]
# optimizer
optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001)
cfg_text
是遍历所有 base 文件,然后读取其文本内容,并且在前面追加文件路径,最后才追加当前文件内容,其返回的内容大致如下:
retinanet_r50_fpn.py 文件绝对路径
retinanet_r50_fpn.py 文件内容
coco_detection.py 文件绝对路径
coco_detection.py 文件内容
...
retinanet_r50_fpn_1x_coco.py 文件绝对路径
_base_ = [
'../_base_/models/retinanet_r50_fpn.py',
'../_base_/datasets/coco_detection.py',
'../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]
# optimizer
optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001)
_file2dict 函数大概逻辑是:
# 1. 先解析最上层文件
mod = import_module(temp_module_name)
cfg_dict = {
name: value
for name, value in mod.__dict__.items()
if not name.startswith('__')
}
if BASE_KEY in cfg_dict:
# 2. 解析 base 文件
for f in base_filename:
_cfg_dict, _cfg_text = Config._file2dict(osp.join(cfg_dir, f))
cfg_dict_list.append(_cfg_dict)
# 3. 不允许多个 base 文件有重复 key
for c in cfg_dict_list:
if len(base_cfg_dict.keys() & c.keys()) > 0:
raise KeyError('Duplicate key is not allowed among bases')
# 4. 合并 base 内容到同一个字典中
base_cfg_dict = Config._merge_a_into_b(cfg_dict, base_cfg_dict)