python-dotenv
下面是一份完整的教程,涵盖了从安装到进阶使用的所有内容,并针对 Python 3.14 环境做了特别说明。
📦 准备工作:安装与兼容性
首先,确保你安装的python-dotenv版本至少是1.2.2,因为从这个版本开始,它才正式添加了对 Python 3.14 的官方支持 。
# 使用 pip 安装,该版本支持 Python 3.10 到 3.14pipinstallpython-dotenv# 如果还想使用命令行工具(CLI),可以这样安装pipinstall"python-dotenv[cli]"安装后,你可以用下面的命令验证一下版本是否满足要求 :
python-c"import dotenv; print(dotenv.__version__)"📝 核心用法:load_dotenv()与.env文件
最常规的用法就是在项目根目录创建一个.env文件,然后在代码入口处加载它。
1. 创建.env文件
在你的项目根目录下创建一个.env文件,语法与 Bash 类似 :
# .env 文件内容示例# 等号两边不能有空格DATABASE_URL="postgresql://user:pass@localhost/db"SECRET_KEY="your-secret-key"# 支持变量引用,注意使用 ${VAR} 的格式DOMAIN=example.orgADMIN_EMAIL=admin@${DOMAIN}特别注意:
.env文件包含敏感信息,务必将其添加到.gitignore文件中,避免泄露 。
2. 在代码中加载
在你的 Python 程序入口文件(如main.py或app.py)的最顶部调用load_dotenv()。一个最常见的错误就是在调用os.getenv()之后才加载,这会导致变量读取不到 。
# main.pyimportosfromdotenvimportload_dotenv# 关键:在一切代码之前加载 .env 文件# 它默认会在当前工作目录查找 .env 文件load_dotenv()# 现在可以安全地读取环境变量了db_url=os.getenv("DATABASE_URL")secret=os.getenv("SECRET_KEY")print(f"Database URL:{db_url}")load_dotenv()默认行为是不覆盖已存在的系统环境变量(override=False)。如果你希望.env文件里的值强制覆盖系统变量,可以传入override=True。
⚙️ 进阶配置与最佳实践
在实际项目中,你可能会遇到更复杂的场景,以下是一些实用的技巧。
精准定位.env文件
load_dotenv()默认查找当前工作目录(即启动脚本时所在的目录)的.env文件。如果项目结构复杂,或者从 IDE 运行,工作目录可能和预期不一致,导致加载失败 。
一个稳健的做法是使用__file__来定位.env文件的绝对路径 :
frompathlibimportPathfromdotenvimportload_dotenv# 获取当前文件所在目录,再定位到项目根目录的 .env 文件env_path=Path(__file__).parent/".env"load_dotenv(dotenv_path=env_path)管理多环境配置(开发、测试、生产)
你可以为不同环境维护不同的配置文件,如.env.dev,.env.prod,然后根据当前环境动态加载 。
importosfromdotenvimportload_dotenv# 根据 ENV 环境变量决定加载哪个文件env=os.getenv("ENV","dev")# 默认是 devload_dotenv(f".env.{env}")# 如果在命令行设置了 ENV=prod,就会加载 .env.prod读取但不修改系统环境变量:dotenv_values
如果你只想读取.env文件的配置,但不想将它们写入os.environ,可以使用dotenv_values函数。它会返回一个包含所有键值对的字典 。
fromdotenvimportdotenv_values config=dotenv_values(".env")print(config.get("DATABASE_URL"))这在你需要合并多个配置文件时非常有用 :
importosfromdotenvimportdotenv_values config={**dotenv_values(".env.shared"),# 基础配置**dotenv_values(".env.secret"),# 敏感配置**os.environ,# 系统环境变量(优先级最高)}在 Python 3.14 中处理类型转换
一个重要注意事项:os.getenv()和dotenv_values()返回的值始终是字符串(或None)。你需要手动将它们转换为预期的类型,特别是在 Python 3.14 中,类型检查可能更严格 。
importos# 获取字符串database_url=os.getenv("DATABASE_URL")# 转换为整数port=int(os.getenv("PORT","8000"))# 转换为布尔值,更严谨的判断debug=os.getenv("DEBUG","false").lower()in("true","1","t")🛠️ 命令行工具 (CLI)
安装带[cli]扩展的版本后,你可以直接在终端操作.env文件,无需手动编辑 。
# 设置变量$ dotenvsetUSERNAME admin# 列出所有变量$ dotenv list# 以 JSON 格式输出$ dotenv list--format=json# 在加载了 .env 文件的环境中运行指定命令$ dotenv run -- python my_script.py🔒 安全与生产环境注意事项
- 生产环境禁用:在生产环境(如服务器、Docker容器)中,建议直接使用系统环境变量(通过
-e参数或编排工具注入),而不是依赖.env文件。python-dotenv专为开发环境设计,但它的override行为保证了系统变量优先级更高 。 - 强制禁用:如果你无法修改第三方代码中的
load_dotenv()调用,可以在环境变量中设置PYTHON_DOTENV_DISABLED=1来全局禁用它 。