[环境管理/Python] dotenv : Python 轻量级环境变量管理库

1 概述: dotenv

  • dotenv 是一个轻量级且必备的工具,用于【管理环境变量】,特别适合初级开发者学习配置管理。

1.1 为什么要用 dotenv

场景 问题 dotenv 解决方案
代码中硬编码密钥 泄露风险、难以维护 分离到 .env 文件
不同环境配置不同 改代码麻烦 一套代码,多套配置
团队协作 每个人配置不同 .env 本地管理,.env.example 共享模板
  • 加载一次,随处读取,文件保密,集中管理,生产脱钩。

1.2 安装与基础用法

安装

pip install python-dotenv

最简示例

  • .env 文件

放在项目根目录,不要提交到 Git

# 数据库配置
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
DEBUG=True
API_KEY=sk-1234567890abcdef
  • Python 代码
from dotenv import load_dotenv
import os

# 加载 .env 文件到环境变量
load_dotenv()

# 像读取普通环境变量一样使用
db_url = os.getenv("DATABASE_URL")
debug_mode = os.getenv("DEBUG", "False") == "True"  # 带默认值
api_key = os.getenv("API_KEY")

print(f"数据库: {db_url}")
print(f"调试模式: {debug_mode}")

1.3 核心 API 详解

load_dotenv() —— 最常用的加载方式

from dotenv import load_dotenv

# 默认行为:从当前工作目录向上查找 .env 文件
load_dotenv()

# 指定具体路径
load_dotenv(dotenv_path="/path/to/.env")

# 自定义 .env 文件名
load_dotenv(dotenv_path=".env.local")

# 不覆盖已存在的环境变量(安全模式)
load_dotenv(override=False)  # 默认 True,会覆盖系统环境变量

find_dotenv() —— 自动查找文件

from dotenv import load_dotenv, find_dotenv

# 自动向上级目录查找 .env
env_path = find_dotenv(raise_error_if_not_found=True)
load_dotenv(env_path)

set_key() / get_key() —— 读写 .env 文件

from dotenv import set_key, get_key

# 读取特定键
value = get_key(".env", "DATABASE_URL")

# 修改或新增键值(会修改文件!)
set_key(".env", "NEW_VAR", "new_value")

1.4 最佳实践(初级工程师必看)

✅ 正确的项目结构

my_project/
├── .env                 # ← 本地配置文件(gitignore)
├── .env.example         # ← 模板文件(提交到git)
├── .gitignore
├── src/
│   └── config.py        # ← 集中管理配置读取
└── main.py

.gitignore 配置

# 忽略所有 .env 文件,但保留模板
.env
.env.local
.env.*.local
!.env.example

.env.example 模板(给团队看)

# 复制此文件为 .env 并填写真实值
DATABASE_URL=postgresql://user:pass@localhost/dbname
DEBUG=False
API_KEY=your_api_key_here
SECRET_KEY=generate_a_random_string

✅ 集中配置管理(推荐模式)

config.py

from dotenv import load_dotenv
from dataclasses import dataclass
import os

load_dotenv()

@dataclass(frozen=True)
class Config:
    """应用配置,只读"""
    DATABASE_URL: str = os.getenv("DATABASE_URL", "")
    DEBUG: bool = os.getenv("DEBUG", "False").lower() == "true"
    API_KEY: str = os.getenv("API_KEY", "")
    PORT: int = int(os.getenv("PORT", "8000"))

# 全局配置实例
config = Config()

# 使用方式
# from config import config
# print(config.DATABASE_URL)

1.5 常见坑与解决方案

原因 解决
修改 .env 后代码没变化 只在导入时加载一次 重启程序或手动重新 load_dotenv()
布尔值判断错误 os.getenv 返回字符串 "True" == "true"str.lower()
多行值解析失败 值包含换行符 用引号包裹:MY_VAR="line1\nline2"
值包含 # 被截断 # 被当注释 用引号包裹:URL="http://a.com#fragment"
生产环境变量不生效 优先级问题 生产环境直接用系统环境变量,不依赖 .env

1.6 快速参考卡片

from dotenv import load_dotenv, find_dotenv
import os

# 标准启动代码
load_dotenv(find_dotenv())

# 读取(带默认值)
value = os.getenv("KEY", "default")

# 类型转换
port = int(os.getenv("PORT", "8080"))
debug = os.getenv("DEBUG", "").lower() in ("true", "1", "yes")

# 检查必填项
required = ["DATABASE_URL", "API_KEY"]
missing = [k for k in required if not os.getenv(k)]
if missing:
    raise ValueError(f"缺少环境变量: {missing}")

1.X 总结

要点 说明
核心功能 把配置从代码分离到 .env 文件
安全原则 .env 永不提交 Git,用 .env.example 模板
架构模式 config.py 集中管理,避免到处 os.getenv
生产部署 云平台直接设置环境变量,不依赖 .env 文件
  • 掌握 dotenv 是写出专业、可维护、安全 Python 代码的第一步

Z FAQ for dotenv

Q:是否支持环境变量的引用?

  • 支持。python-dotenv 支持在 .env 文件中使用 ${VAR}$VAR 语法引用其他环境变量。

用法示例

  • .env 文件
# 基础变量
BASE_PATH=/home/user/project

# 引用语法
DATA_DIR=${BASE_PATH}/data
LOG_DIR=$BASE_PATH/logs        # 简写形式也可

# 嵌套引用 + 默认值(需启用 interpolate)
FULL_URL=${PROTOCOL:-https}://${HOST:-localhost}:${PORT:-8080}
  • Python 代码
from dotenv import load_dotenv
import os

# 关键:启用 interpolate=True(默认已开启)
load_dotenv(interpolate=True)

print(os.getenv("DATA_DIR"))   # /home/user/project/data
print(os.getenv("LOG_DIR"))    # /home/user/project/logs
print(os.getenv("FULL_URL"))   # https://localhost:8080

关键特性速查

  • 语法 : ${VAR} | $VAR | ${VAR:-default} | ${VAR:?error}
  • 说明 : 标准引用 | 简写引用(仅限简单场景) | 默认值 | 缺失报错
  • 示例 : ${BASE}/subdir | $BASE/subdir | ${PORT:-3000} | ${SECRET:?required}

注意事项

# 禁用插值(纯文本模式)
load_dotenv(interpolate=False)  # 原样保留 ${XXX} 字符串

# 循环引用会报错
# A=$B 且 B=$A → dotenv.main.DotEnvInterpolationError

# 系统环境变量优先级高于 .env 内定义
# 若 export BASE_PATH=/system,则 .env 中 BASE_PATH 被覆盖

实际应用

# .env
PROJECT_NAME=myapp
VERSION=1.0.0
IMAGE_TAG=${PROJECT_NAME}:${VERSION}      # myapp:1.0.0
COMPOSE_PROJECT_NAME=${PROJECT_NAME}_dev  # myapp_dev
  • 总结${} 语法原生支持,适合构建路径、标签等组合值,但避免循环依赖。

Y 推荐文献

X 参考文献

posted @ 2026-03-28 09:14  千千寰宇  阅读(29)  评论(0)    收藏  举报