如何保存/恢复含继承属性的Python类配置结构?
解决继承式配置类的无依赖保存与恢复问题
你遇到的核心问题很典型:pickle依赖原类定义导致恢复报错,而直接取实例__dict__只能拿到被修改过的属性,没法获取继承来的完整配置。下面给你一套完全无需依赖原类定义的可行方案:
为什么vars(cfg)只能拿到部分属性?
继承来的配置属性属于类属性,只有当你在实例中修改过某个属性时,它才会被添加到实例的__dict__里。父类中未被覆盖的属性默认存在于父类的__dict__中,不会出现在实例的__dict__里,所以直接用vars(cfg)只能拿到你后来修改的NAME='ABC'。
完整解决方案:转成完整字典后保存为JSON
我们可以写一个工具函数,递归收集所有继承链上的类属性,再合并实例自身的属性,最终得到包含所有配置项的完整字典,然后用JSON保存(JSON是无依赖的序列化格式,恢复时不需要原类)。
步骤1:编写配置转字典的函数
这个函数会遍历配置类的所有父类(包括自身),过滤掉方法和私有属性,再合并实例的修改:
def cfg_to_full_dict(cfg): full_config = {} # 遍历类的继承链(从子类到父类) for cls in type(cfg).__mro__: if cls == object: continue # 过滤掉私有属性和可调用的方法 for key, value in cls.__dict__.items(): if not key.startswith('_') and not callable(value): full_config[key] = value # 用实例的属性覆盖类属性(比如你后来修改的NAME='ABC') full_config.update(vars(cfg)) return full_config
步骤2:保存配置到JSON文件
import json # 假设你的cfg实例已经准备好 cfg = Config() cfg.NAME = 'ABC' # 生成完整配置字典 full_cfg_dict = cfg_to_full_dict(cfg) # 保存到JSON with open('config.json', 'w', encoding='utf-8') as f: json.dump(full_cfg_dict, f, indent=2, ensure_ascii=False)
步骤3:无依赖恢复配置
恢复时不需要原Config类,直接把JSON转成字典,或者转成SimpleNamespace方便用点语法访问:
from types import SimpleNamespace import json with open('config.json', 'r', encoding='utf-8') as f: cfg_dict = json.load(f) # 转成类似类实例的对象,支持cfg.NAME这样的访问方式 cfg = SimpleNamespace(**cfg_dict) # 验证一下 print(cfg.GPU_COUNT) # 输出2(来自experiment1.py的Config类) print(cfg.NAME) # 输出ABC(来自运行时修改) print(cfg.MAP) # 输出{1:2, 2:3}(来自父类Config)
额外说明
- 如果你的配置里有JSON无法序列化的类型(比如numpy数组、自定义对象),可以先把这些类型转成JSON支持的格式(比如数组转成列表),再保存;恢复时再转回去。
- 这个方案完全脱离了原类的依赖,你可以在任何环境中恢复配置,只要能读取JSON即可。
内容的提问来源于stack exchange,提问作者YW P Kwon
相关产品推荐
相关产品推荐

