如何将配置模块通过Mixin类实现重构?

摘要:前言 按照个人习惯,项目伊始我会按照如下结构组织项目配置,也就是配置文件放在conf目录,单独写一个配置模块pkgconfig.py去读取加载。有的小项目还好,没什么配置项。但有的项目要调用很多第三方的接口,配置文件写了一堆接口地址、认
前言 按照个人习惯,项目伊始我会按照如下结构组织项目配置,也就是配置文件放在conf/目录,单独写一个配置模块pkg/config.py去读取加载。有的小项目还好,没什么配置项。但有的项目要调用很多第三方的接口,配置文件写了一堆接口地址、认证方式等,配置模块也相应增加了几百行。看着这快上千行的配置模块,还是尽早改改比较好。 conf/ app.toml pkg/ config.py 有的项目会把配置打散,各个模块维护各自的配置,但对于使用单一配置模块的项目,除了配置模块,其它模块调用配置类单例的地方我都不想去碰,也懒得碰。这时候,使用Mixin类就比较合适。 在Python中,Mixin只是一种约定,语言层面没有显式支持,实际上就是python的多重继承。 旧代码的配置类 旧的配置模块pkg/config.py大概长这样,每个配置项都写成了动态属性。即便只是简单的取值,也可能会写很多。如果再加上校验,单个文件的内容就会很多了,鼠标滚轮翻快点估计就找不到哪对哪了。 class Config: def __init__(self) -> None: self._config_file = Path(__file__).parent.parent.parent / "conf" / "config.toml" self._config = self._load_config() def _load_config(self) -> Dict[str, Any]: if not self._config_file.exists(): raise FileNotFoundError(f"Configuration file {self._config_file} does not exist.") with open(self._config_file, "rb") as f: return tomllib.load(f) @property def service_host(self) -> str: return self._config.get("service").get("host", "127.0.0.1") @property def service_port(self) -> int: return self._config.get("service").get("port", 8000) 拆分 简单示例 如果配置的层级特别深,Mixin里写一长串.get().get()也挺碍眼的。可以写一个基类BaseMixin,在基类中定义一个递归读取配置的方法。
阅读全文