Python 配置管理
配置与代码分离:环境变量、文件与密钥边界;校验失败要早且明确。
#type / concept
#status / growing
#tech / dev
#resource / python
#tech / lang / python
[!info] 关联笔记
Python 配置管理
这个概念为什么出现
把数据库密码写进代码仓库是事故。配置应:
- 按环境变化
- 可校验
- 密钥不进 git
[!abstract] 一句话理解 从环境/文件加载配置并校验类型与必填项;代码只读配置对象,密钥走密钥管理。
最小可运行示例
先把示例放进业务场景,再看代码:
场景:服务启动读取超时与数据库 URL
# config_from_env.py
# 业务意图:从环境变量构建配置,缺省与校验。
# 教学点:
# - os.environ;
# - 默认值;
# - 启动期失败。
import os
from dataclasses import dataclass
@dataclass(frozen=True)
class AppConfig:
database_url: str
request_timeout_s: float
def load_config(env: dict[str, str] | None = None) -> AppConfig:
e = env if env is not None else os.environ
url = e.get("DATABASE_URL")
if not url:
raise RuntimeError("DATABASE_URL is required")
timeout = float(e.get("REQUEST_TIMEOUT_S", "3"))
if timeout <= 0:
raise RuntimeError("REQUEST_TIMEOUT_S must be positive")
return AppConfig(database_url=url, request_timeout_s=timeout)
def main() -> None:
cfg = load_config({"DATABASE_URL": "postgres://local/app", "REQUEST_TIMEOUT_S": "5"})
print(cfg)
if __name__ == "__main__":
main()
建议运行:
python config_from_env.py
期望输出:
AppConfig(database_url='postgres://local/app', request_timeout_s=5.0)
结合场景再看三个关注点
- 缺必填直接启动失败,避免半残运行。
- frozen 配置防运行中被改。
- 真实系统可用 pydantic-settings 等。
核心概念与准确模型
- 12-factor:配置存环境
- 分层:默认 < 文件 < 环境 < 命令行
- 密钥与普通配置分离
- 特性开关
边界情况与反直觉行为
- 空字符串 vs 未设置。
- 类型转换失败要明确错误。
- 容器与本地路径差异。
常见误区
[!warning] 常见误区:配置散落 os.getenv 到处调用 错误理解:随手读环境。
正确模型:集中加载一次,注入依赖。
工程实践
- 示例
.env.example无密钥 - 启动打印非敏感配置摘要
- 测试注入 env dict
本节总结
配置是产品行为的一部分。集中、校验、保密。
自测题
- 为何启动时校验配置?
- 密钥为何不进仓库?
参考答案
- 失败早、定位易,避免请求中才爆。
- 泄露面与权限失控;应用轮换困难。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| os.environ | 文档 | 环境变量 |
| 12-factor Config | 方法论 | 配置原则 |