Python 使用“繼承”來管理yaml文件
- 引言
引言
在 Python 中有時候我們會把參數都儲存在yaml
文件中然后進行調用。當我們在進行一個很大的項目的時候,我們可能先需要一個base.yaml
文件,然后再使用一個task1.yaml
文件進行參數導入,并且task1.yaml
文件繼承base.yaml
文件,這時候我們應該如何使用呢?
def load_config(path, default_path=None, demo_train_eval='train'):''' Loads config file.Args: path (str): path to config filedefault_path (bool): whether to use default path'''assert demo_train_eval in ['datagen', 'demo', 'train', 'eval'], f'Invalid value for "demo_train_eval" ({demo_train_eval}) in load_config!'# Load configuration from file itselfwith open(path, 'r') as f:cfg_special = yaml.safe_load(f)# Check if we should inherit from a configinherit_from = cfg_special.get('inherit_from')# If yes, load this config first as default# If no, use the default_pathif inherit_from is not None:if demo_train_eval == 'train':cfg = load_config(osp.join(path_util.get_train_config_dir(), inherit_from))elif demo_train_eval == 'eval':cfg = load_config(osp.join(path_util.get_eval_config_dir(), inherit_from))elif demo_train_eval == 'demo':cfg = load_config(osp.join(path_util.get_demo_config_dir(), inherit_from))elif demo_train_eval == 'datagen':cfg = load_config(osp.join(path_util.get_data_gen_config_dir(), inherit_from))else:raise ValueError(f'Argument "demo_train_eval" must be either "train", "demo", or "eval", value {demo_train_eval} not recognized')elif default_path is not None:with open(default_path, 'r') as f:cfg = yaml.safe_load(f)else:cfg = dict()# Include main configurationupdate_recursive(cfg, cfg_special)return cfgdef update_recursive(dict1: dict, dict2: dict) -> dict:''' Update two config dictionaries recursively.Args:dict1 (dict): first dictionary to be updateddict2 (dict): second dictionary which entries should be used'''for k, v in dict2.items():if k not in dict1:dict1[k] = dict()if isinstance(v, dict):update_recursive(dict1[k], v)else:dict1[k] = v