如何在Python中将模块中的共享config对象设置为readonly(只读)?
如何让Python模块中的配置对象只读且共享?
推荐几种可行的方案来实现模块中config对象的只读保护:
方案1:使用标准库的types.MappingProxyType
这是最简便的原生方案,专门用于创建字典的只读代理,无需额外安装依赖。修改configure.py如下:
import yaml import types with open("config.yaml","r") as f: _config = yaml.load(f) # 创建只读代理 config = types.MappingProxyType(_config)
当其他脚本尝试修改config时(比如config["attr"] = "new_value"),会直接抛出TypeError: 'mappingproxy' object does not support item assignment错误,完全阻止修改操作。
注意:如果配置里有嵌套字典,MappingProxyType仅保护顶层字典,内部嵌套的字典仍可修改。要实现完全嵌套只读,需要递归转换所有内层结构:
import yaml import types def make_readonly(obj): if isinstance(obj, dict): return types.MappingProxyType({k: make_readonly(v) for k, v in obj.items()}) elif isinstance(obj, list): return tuple(make_readonly(item) for item in obj) # 列表转为不可变元组 else: return obj with open("config.yaml","r") as f: _config = yaml.load(f) config = make_readonly(_config)
方案2:自定义只读包装类
如果需要更灵活的控制(比如自定义错误提示),可以自己实现一个只读字典类:
import yaml class ReadOnlyDict(dict): def __setitem__(self, key, value): raise TypeError("配置对象是只读的,不允许修改") def __delitem__(self, key): raise TypeError("配置对象是只读的,不允许删除") def update(self, *args, **kwargs): raise TypeError("配置对象是只读的,不允许更新") def pop(self, *args, **kwargs): raise TypeError("配置对象是只读的,不允许弹出元素") def popitem(self): raise TypeError("配置对象是只读的,不允许弹出元素") def clear(self): raise TypeError("配置对象是只读的,不允许清空") with open("config.yaml","r") as f: _config = yaml.load(f) def convert_to_readonly(obj): if isinstance(obj, dict): return ReadOnlyDict({k: convert_to_readonly(v) for k, v in obj.items()}) elif isinstance(obj, list): return tuple(convert_to_readonly(item) for item in obj) else: return obj config = convert_to_readonly(_config)
这种方式可以自定义错误信息,且能覆盖所有修改字典的内置方法,彻底防止误改。
方案3:使用第三方库frozendict
frozendict是专门的不可变字典库,支持嵌套不可变,使用便捷。先安装依赖:
pip install frozendict
再修改configure.py:
import yaml from frozendict import deepfrozendict with open("config.yaml","r") as f: _config = yaml.load(f) config = deepfrozendict(_config)
deepfrozendict会递归将整个配置结构转为不可变,任何修改操作都会抛出错误。
内容的提问来源于stack exchange,提问作者Siuol Lee
相关产品推荐
相关产品推荐

