from __future__ import annotations import os from pathlib import Path def load_env_file(path: Path) -> None: # .env 文件不存在时允许继续使用外部环境变量。 if not path.exists(): return # 逐行读取 .env 内容。 for raw_line in path.read_text(encoding="utf-8").splitlines(): # 先去掉两端空白。 line = raw_line.strip() # 空行不处理。 if not line: continue # 注释不处理。 if line.startswith("#"): continue # 不符合 KEY=VALUE 结构的行直接跳过。 if "=" not in line: continue # 只按第一个等号拆分,避免 value 里包含额外等号时被误切。 key, value = line.split("=", 1) # 清理 key 和 value 两端的空白。 key = key.strip() value = value.strip() # 去掉成对双引号。 if value.startswith('"') and value.endswith('"'): value = value[1:-1] # 去掉成对单引号。 if value.startswith("'") and value.endswith("'"): value = value[1:-1] # 只在外部环境没有显式传入时才写入。 os.environ.setdefault(key, value) def env_str(name: str, default: str = "") -> str: # 读取字符串环境变量。 value = os.environ.get(name, default) # 返回去掉两端空白后的结果。 return value.strip() def env_int(name: str, default: int) -> int: # 先按字符串读取。 raw_value = env_str(name, str(default)) # 转成整数返回。 return int(raw_value) def env_float(name: str, default: float) -> float: # 先按字符串读取。 raw_value = env_str(name, str(default)) # 转成浮点数返回。 return float(raw_value) def env_int_list(name: str, default: list[int]) -> tuple[int, ...]: # 先读取原始文本。 raw_value = env_str(name, "") # 没配置时直接返回默认值。 if not raw_value: return tuple(default) # 逐项切分并过滤空项。 values = [item.strip() for item in raw_value.split(",") if item.strip()] # 转成整数元组返回。 return tuple(int(item) for item in values)