1. 什么是 pydantic-settings? #
pydantic-settings 是一个基于 Pydantic 的配置管理库,用来从环境变量、.env 文件等来源加载配置,并自动做类型校验和转换。
通俗理解:你的程序需要「数据库地址」「API 密钥」等配置。传统做法是到处写 os.environ.get("XXX"),类型不明确、容易出错。pydantic-settings 让你定义一个「配置类」,字段有类型、有默认值,库会自动从环境变量和 .env 里读出来并校验,用起来就像访问普通属性。
2. 前置知识:环境变量与 .env #
2.1 环境变量 #
环境变量 是操作系统或进程中的键值对,程序可以读取。例如在终端执行 set API_KEY=sk-xxx(Windows)或 export API_KEY=sk-xxx(Linux/Mac),程序里用 os.environ.get("API_KEY") 就能拿到 sk-xxx。
2.2 .env 文件 #
.env 是放在项目根目录的文本文件,每行一个 KEY=VALUE。配合 python-dotenv 或 pydantic-settings,程序启动时会自动加载,无需在终端里手动设置。例如:
DATABASE_URL=postgresql://localhost/mydb
DEBUG=true3. 安装 #
pip install pydantic-settings若使用 uv:uv add pydantic-settings
4. 示例 #
下面示例定义配置并从环境变量或 .env 加载。
# 导入 BaseSettings,用于定义配置类
from pydantic_settings import BaseSettings
# 定义配置类:继承 BaseSettings,字段即配置项
class Settings(BaseSettings):
# 应用名称,有默认值,未设置环境变量时使用
app_name: str = "MyApp"
# 是否调试模式,默认 False
debug: bool = False
# 数据库地址,无默认值,必须通过环境变量或 .env 提供
database_url: str = "sqlite:///./demo.db"
# 实例化配置:自动从环境变量和 .env 加载
settings = Settings()
# 使用配置
print(settings.app_name)
print(settings.debug)
print(settings.database_url)运行方式:保存为 config_demo.py,执行 python config_demo.py。若项目根目录有 .env 且包含 DATABASE_URL=xxx,会优先使用该值;否则使用默认值 sqlite:///./demo.db。
5. 环境变量前缀(env_prefix) #
当多个项目共用同一台机器时,可用前缀区分环境变量,避免冲突。
# 导入 BaseSettings 和 SettingsConfigDict
from pydantic_settings import BaseSettings, SettingsConfigDict
# 配置类:通过 model_config 设置 env_prefix
class Settings(BaseSettings):
app_name: str = "MyApp"
debug: bool = False
# 环境变量前缀:MYAPP_,即读取 MYAPP_APP_NAME、MYAPP_DEBUG
model_config = SettingsConfigDict(env_prefix="MYAPP_")
# 实例化
settings = Settings()
# 使用配置
print(settings.app_name)
print(settings.debug)说明:设置了 env_prefix="MYAPP_" 后,会读取 MYAPP_APP_NAME、MYAPP_DEBUG。若未设置这些变量,则使用默认值。
6. 加载 .env 文件 #
pydantic-settings 默认会尝试加载 .env。可通过 env_file 指定路径或文件名。
# 导入 BaseSettings 和 SettingsConfigDict
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
app_name: str = "MyApp"
api_key: str = ""
# 指定 .env 文件路径,默认会查找项目根目录的 .env
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
)
settings = Settings()
print(f"app_name: {settings.app_name}, api_key: {'***' if settings.api_key else '(空)'}")运行方式:在项目根目录创建 .env,内容例如:
APP_NAME=我的应用
API_KEY=sk-xxx保存后运行脚本,会优先使用 .env 中的值。
7. 配置优先级 #
配置按以下优先级从高到低生效(高优先级覆盖低优先级):
| 优先级 | 来源 | 说明 |
|---|---|---|
| 1 | 初始化参数 | Settings(database_url="xxx") |
| 2 | 环境变量 | 系统或终端中设置 |
| 3 | .env 文件 | 项目中的 .env |
| 4 | 默认值 | 字段定义时的默认值 |
8. 自定义环境变量名(Field) #
若希望环境变量名与字段名不同,可用 Field 的 validation_alias 指定。
# 导入 BaseSettings 和 Field
from pydantic_settings import BaseSettings
from pydantic import Field
class Settings(BaseSettings):
# 字段名为 api_key,但从环境变量 MY_SECRET_KEY 读取
api_key: str = Field(default="", validation_alias="MY_SECRET_KEY")
settings = Settings()
print(settings.api_key)说明:程序会读取 MY_SECRET_KEY,而不是 API_KEY。
9. 嵌套配置(嵌套模型) #
当配置项较多时,可拆成嵌套结构,用 __ 分隔的环境变量映射到嵌套字段。
# 导入 BaseModel、BaseSettings 和 SettingsConfigDict
from pydantic import BaseModel
from pydantic_settings import BaseSettings, SettingsConfigDict
# 数据库子配置
class DatabaseConfig(BaseModel):
host: str = "localhost"
port: int = 5432
# 主配置:包含嵌套的 db
class Settings(BaseSettings):
db: DatabaseConfig = DatabaseConfig()
app_name: str = "MyApp"
# 嵌套分隔符:DB__HOST 映射到 db.host
model_config = SettingsConfigDict(env_nested_delimiter="__")
settings = Settings()
print(settings.db.host)
print(settings.db.port)说明:设置 env_nested_delimiter="__" 后,DB__HOST 会映射到 settings.db.host,DB__PORT 映射到 settings.db.port。
10. 多环境配置 #
# 导入 BaseSettings、SettingsConfigDict 和 Field
from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic import Field
# 定义配置类
class Settings(BaseSettings):
# 应用名称
app_name: str = "MyApp"
# 环境:development / production
environment: str = "development"
# 是否调试
debug: bool = False
# 数据库地址
database_url: str = "sqlite:///./app.db"
# API 密钥(敏感信息,建议从环境变量读取)
api_key: str = Field(default="", validation_alias="API_KEY")
# 模型配置
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
extra="ignore",
)
# 全局单例:只实例化一次,多处复用
settings = Settings()
# 主程序
if __name__ == "__main__":
print(settings.model_dump())运行方式:保存为 settings.py,执行 python settings.py。可创建 .env 覆盖部分配置。
11. 最佳实践 #
- 单例:在单独模块(如
config.py)中定义并实例化,全局只创建一次。 - 敏感信息:API 密钥、密码等通过环境变量或
.env加载,不要硬编码。 - 多环境:开发用
.env,生产用.env.prod或环境变量。 - extra="ignore":忽略未在模型中定义的环境变量,避免报错。
12. 总结 #
- pydantic-settings 用
BaseSettings定义配置类,自动从环境变量和.env加载并校验。 - env_prefix 指定环境变量前缀,env_file 指定
.env路径。 - Field(validation_alias="xxx") 可自定义环境变量名。
- env_nested_delimiter 支持嵌套配置,如
DB__HOST映射到db.host。