import os from pathlib import Path from types import SimpleNamespace # 导入SimpleNamespace from typing import Any, Dict import yaml from dotenv import load_dotenv from loguru import logger class EnvConfig: def __init__(self): # 加载环境变量 if os.path.exists(".env"): if load_dotenv(".env"): logger.info("[激活配置] .env 配置加载成功 ✅") else: # 将 exit(1) 更改为 warning,避免程序直接退出 logger.warning( "[激活配置] 环境变量加载失败,请检查 .env 文件内容是否正确" ) else: logger.warning("[激活配置] .env 文件不存在,将不加载环境变量") def _parse_bool(self, value): """将字符串形式的布尔值转换为布尔类型""" if isinstance(value, str): if value.lower() == "true": return True elif value.lower() == "false": return False return value def __getattr__(self, name): value = os.getenv(name) if value is not None: return self._parse_bool(value) default_name = f"DEFAULT_{name}" default_value = os.getenv(default_name) if default_value is not None: return self._parse_bool(default_value) return None def get(self, name, default=None): value = os.getenv(name) if value is not None: return self._parse_bool(value) return default class YamlConfig: def __init__(self, yaml_file: str = "config.yaml"): self._yaml_file = Path(yaml_file) self._load_settings() def _load_settings(self) -> None: if not self._yaml_file.exists(): raise FileNotFoundError(f"[激活配置] 配置文件 {self._yaml_file} 不存在") with open(self._yaml_file, "r", encoding="utf-8") as f: config_data = yaml.safe_load(f) or {} self._set_attributes(config_data) logger.info("[激活配置] config.yaml 配置加载成功 ✅") def _set_attributes(self, config_data: Dict[str, Any]) -> None: # 使用 SimpleNamespace 更好地处理嵌套配置,使其可以通过属性访问 for key, value in config_data.items(): if isinstance(value, dict): setattr(self, key, SimpleNamespace(**value)) else: setattr(self, key, value) # 移除 _from_dict 方法,因为 SimpleNamespace 可以直接从字典创建 def __repr__(self) -> str: attrs = [] for key in sorted(self.__dict__.keys()): if not key.startswith("_"): value = getattr(self, key) attrs.append(f"{key}={repr(value)}") return f"Settings({', '.join(attrs)})" def reload(self) -> None: if self._yaml_file is None: raise RuntimeError("无法重新加载,此实例是从字典创建的") self._load_settings() # 创建配置实例 env_config = EnvConfig() yaml_config = None try: yaml_config = YamlConfig() except FileNotFoundError: logger.warning("[激活配置] 配置文件 config.yaml 不存在,将不加载配置") class Setting: def __init__(self): self.env = env_config self.config = yaml_config setting = Setting()