Pydantic 2.x 中 BaseSettings 已移至独立包 pydantic-settings,需卸载 pydantic 并安装 pydantic-settings;字段类型决定环境变量自动转换与校验行为,支持 bool、float、list[str] 等类型解析,环境变量名默认大写蛇形,可通过 env_prefix 或 Field(alias=...) 自定义,缺失变量建议设默认值或 default_factory 提升可维护性。

pydantic 2.x 中用 BaseSettings 读取环境变量已废弃,必须改用 pydantic-settings
如果你还在用 from pydantic import BaseSettings,运行时会报 ImportError: cannot import name 'BaseSettings' from 'pydantic'。这是 pydantic v2.0+ 的硬性变更——环境变量加载逻辑被拆进独立包 pydantic-settings,不装它就根本跑不起来。
正确做法是:
- 卸载旧版:
pip uninstall pydantic(确保不是 v1) - 安装新组合:
pip install pydantic-settings - 导入改为:
from pydantic_settings import BaseSettings
定义 Settings 类时,字段类型直接决定校验行为
pydantic 不靠注释或额外装饰器,只认类型提示。写 port: int 就真会把 PORT=8080 转成整数;如果实际值是 PORT=abc,启动时立刻抛 ValidationError,不会等到你用的时候才发现。
常见类型对应行为:
立即学习“Python免费学习笔记(深入)”;
-
debug: bool→ 自动识别DEBUG=true、DEBUG=1、DEBUG=on等等,大小写不敏感 -
timeout: float→ 支持TIMEOUT=3.5,但TIMEOUT=inf会失败(除非显式用float('inf')) -
allowed_hosts: list[str]→ 依赖ALLOWED_HOSTS=localhost,127.0.0.1这种逗号分隔字符串,自动拆分并校验每个元素为 str -
database_url: str→ 若需进一步校验格式(如是否为合法 URL),得加@field_validator或用AnyUrl类型
环境变量名默认大写 + 下划线,但可通过 env_prefix 或 Field(..., alias=...) 调整
默认规则很死板:类字段 db_host 对应环境变量 DB_HOST;apiTimeout(驼峰)会被转成 API_TIMEOUT。想自定义,有两个入口:
- 全局前缀:
class Settings(BaseSettings): class Config: env_prefix = "MYAPP_"→ 字段port变成读MYAPP_PORT - 单字段别名:
log_level: str = Field(..., alias="LOGLEVEL")→ 强制读LOGLEVEL而非LOG_LEVEL - 注意:
alias仅影响读取,序列化输出仍用字段名;且alias和env_prefix可共存,最终变量名是env_prefix + alias.upper()
缺失必填变量时的报错不够友好,建议显式设默认值或用 Field(default_factory=...)
比如定义 secret_key: str 但没设默认值,又没提供 SECRET_KEY 环境变量,就会报类似 field required (type=value_error.missing) 的泛错误。用户根本不知道该配啥。
更实用的做法:
- 开发环境给占位值:
secret_key: str = "dev-secret-change-in-prod" - 区分环境用工厂函数:
debug: bool = Field(default_factory=lambda: os.getenv("ENV") == "development") - 敏感字段留空但标记:
password: str = Field(..., exclude=True)避免日志泄露
真正难搞的是那种“必须存在但值由外部注入”的场景——比如 Kubernetes Secret 挂载的文件路径。这时得配合 Field(default_factory=... 去读文件内容,而不是依赖环境变量字符串本身。


















