Python中动态导入的类变量如何随配置变量实时更新?
问题描述
我有如下简化后的代码结构:
配置模块 _cfg.py
cfg_var1 = 'old_value'
包含类的模块 _io.py
import _cfg as cfg class class1: class1_vars = {'var1': cfg.cfg_var1}
用户交互脚本 user.py
import _cfg as cfg import _io as io def main(): cfg.cfg_var1 = 'new_value' print(io.class1.class1_vars['var1']) if __name__ == "__main__": main()
运行user.py时,明明已经把cfg.cfg_var1改成了new_value,但io.class1.class1_vars['var1']输出的还是old_value。我知道原因是类变量在模块加载时就已完成赋值,不会自动更新,但不想每次修改配置时还要追踪所有用到它的类重新声明。请问怎么让类变量在被使用时自动获取当前的_cfg变量值?
解决方案
方法1:将类变量改为类属性(@classmethod + @property)
这是最简洁的方案,改动最小,不需要修改user.py的调用方式。修改_io.py:
import _cfg as cfg class class1: @classmethod @property def class1_vars(cls): # 每次访问时动态生成字典,读取最新配置 return {'var1': cfg.cfg_var1}
之后再访问io.class1.class1_vars['var1'],每次都会实时获取cfg.cfg_var1的当前值。
方法2:自定义动态字典类
如果需要保持类变量看起来像普通字典,可以写一个简单的动态字典类,在取值时实时拉取配置:
import _cfg as cfg class DynamicDict: def __getitem__(self, key): # 根据key返回对应最新配置 if key == 'var1': return cfg.cfg_var1 # 其他配置项可以在这里扩展 raise KeyError(key) class class1: class1_vars = DynamicDict()
这种方式和原代码的访问逻辑完全一致,用户感知不到底层的动态获取过程。
方法3:用可变对象包装配置值
如果可以修改配置模块的结构,把配置值放在可变对象(比如字典)里,这样所有引用都会指向同一个对象,修改后自动同步:
修改_cfg.py:
# 用字典包装所有配置项 config = {'var1': 'old_value'}
修改_io.py:
import _cfg as cfg class class1: # 直接引用这个可变字典 class1_vars = cfg.config
修改user.py:
import _cfg as cfg import _io as io def main(): cfg.config['var1'] = 'new_value' print(io.class1.class1_vars['var1']) if __name__ == "__main__": main()
这个方案需要调整所有访问配置的代码,但好处是配置变更时完全不需要关心下游模块的引用。
内容的提问来源于stack exchange,提问作者kinetic_dust
相关产品推荐
相关产品推荐

