Python使用dotenv读取环境变量的示例详解
在开发 Python 应用时,你是否曾遇到过这些问题?
- 数据库密码、API 密钥等敏感信息直接写在代码里,不小心提交到 GitHub 被公开?
- 开发、测试、生产环境需要不同的配置,每次部署都要手动修改代码?
- 团队协作时,每个人的本地配置不同,导致“在我机器上能跑”?
这些问题的根源,往往在于配置与代码没有分离。而解决之道,就是使用 环境变量(Environment Variables) + python-dotenv 工具。
本文将带你从零开始,系统掌握如何用 python-dotenv 安全、灵活地管理 Python 项目的配置,并重点讲解多环境(开发/测试/生产)下的最佳实践。
为什么需要环境变量
环境变量是操作系统提供的一种键值对存储机制,常用于:
- 存放数据库连接地址、密钥、第三方服务 Token 等敏感信息
- 控制应用行为(如是否开启调试模式)
- 实现同一份代码在不同环境下运行不同配置
核心原则:配置不属于代码,应与代码分离。
- 正确做法:代码中通过 os.getenv(“DB_URL”) 获取配置
- 错误做法:代码中硬编码 DB_URL = “postgres://user:pass@localhost/db”
但问题来了:每次运行程序前,都要手动 export DB_URL=… 吗?太麻烦!
这时,.env 文件 + python-dotenv 就派上用场了。
什么是 python-dotenv?
python-dotenv 是一个轻量级 Python 包,它的作用是:
自动从项目中的 .env 文件读取环境变量,并将其加载到当前 Python 进程的环境变量中。
这样,你只需维护一个 .env 文件,无需手动设置系统环境变量,也无需把敏感信息写进代码。
安装
pip install python-dotenv
基础用法:创建并加载 .env 文件
1. 项目结构
建议将 .env 放在项目根目录:
my_app/
├── .env # ← 环境变量文件(不要提交到 Git!)
├── app.py # 主程序
└── .gitignore # 必须忽略 .env
2. 编写 .env 文件
.env 是纯文本文件,格式为 KEY=VALUE,每行一个变量:
# .env DATABASE_URL=postgresql://user:password@localhost/mydb SECRET_KEY=my_super_secret_key_123! DEBUG=True API_TIMEOUT=30
高级语法支持
多行值(用双引号包裹):
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEA... -----END RSA PRIVATE KEY-----"
变量引用(使用 ${VAR}):
PROJECT_DIR=/home/user/my_app
LOG_PATH=${PROJECT_DIR}/logs
注意:.env 中的值始终是字符串,布尔值或数字需在代码中转换。
3. 在 Python 中加载并读取
# app.py
from dotenv import load_dotenv
import os
# 自动加载 ./.env 文件
load_dotenv()
# 读取变量
db_url = os.getenv("DATABASE_URL")
secret = os.getenv("SECRET_KEY")
debug = os.getenv("DEBUG", "False").lower() == "true" # 转为布尔值
timeout = int(os.getenv("API_TIMEOUT", "10")) # 转为整数
print(f"Debug mode: {debug}")
print(f"DB URL: {db_url}")
最佳实践:始终为 os.getenv() 提供默认值,避免因变量缺失导致崩溃。
安全第一:保护你的 .env 文件
.env 通常包含高度敏感信息,必须做到:
1. 永远不要提交到版本控制!
在 .gitignore 中加入:
# .gitignore .env .env.local .env.* # 忽略所有 .env 开头的文件(除非明确需要共享)
2. 团队协作怎么办?
提供一个模板文件,如 .env.example,包含占位符但无真实值:
# .env.example DATABASE_URL=your_database_url_here SECRET_KEY=generate_a_strong_random_key DEBUG=True
新成员复制该文件为 .env 并填入自己的配置。
重点!多环境配置管理(开发 / 测试 / 生产)
真实项目通常有多个运行环境,每个环境需要不同的配置。硬编码或频繁修改 .env 显然不可持续。
解决方案:使用多个 .env 文件
| 环境 | 文件名 | 用途说明 |
|---|---|---|
| 共享配置 | .env.shared | 所有环境通用的非敏感配置 |
| 开发环境 | .env.development | 本地开发使用(如启用 DEBUG) |
| 测试环境 | .env.testing | CI/CD 或自动化测试专用 |
| 生产环境 | .env.production | 线上服务器使用(高安全要求) |
如何加载指定环境的配置
你可以根据当前环境动态加载对应的 .env 文件:
# config.py
import os
from dotenv import load_dotenv, dotenv_values
# 1. 先加载共享配置
load_dotenv(".env.shared")
# 2. 再根据 ENV 环境变量加载特定配置
env = os.getenv("ENV", "development") # 默认为开发环境
if env == "production":
load_dotenv(".env.production", override=True)
elif env == "testing":
load_dotenv(".env.testing", override=True)
else:
load_dotenv(".env.development", override=True)
# 现在 os.getenv() 可获取最终合并后的变量
关键参数:override=True 表示新加载的变量会覆盖已存在的同名变量。
启动应用时指定环境
# 开发 ENV=development python app.py # 生产 ENV=production gunicorn app:app
更高级方案:使用 dotenv_values 返回字典(不污染全局环境)
如果你不想修改全局 os.environ(例如在单元测试中),可以用 dotenv_values:
from dotenv import dotenv_values
# 合并多个配置文件
shared = dotenv_values(".env.shared")
dev = dotenv_values(".env.development")
config = {**shared, **dev} # 后者覆盖前者
print(config["DATABASE_URL"])
这种方式更可控,适合复杂场景。
常见问题与最佳实践
Q1: .env 和系统环境变量冲突怎么办?
A: load_dotenv(override=False)(默认)不会覆盖已存在的系统变量;设为 True 则会覆盖。建议优先使用系统变量,.env 仅作开发时的默认值。
Q2: 如何验证变量是否加载成功?
A: 打印 os.environ 的子集,或使用日志记录关键配置(注意:不要打印敏感值!)。
总结
| 能力 | 说明 |
|---|---|
| 安全隔离 | 敏感信息不出现在代码中 |
| 灵活配置 | 一套代码,多套配置 |
| 团队友好 | 通过 .env.example 统一规范 |
| 多环境支持 | 开发/测试/生产无缝切换 |
| 简单易用 | 3 行代码即可集成 |
python-dotenv 虽小,却是现代 Python 开发不可或缺的工具。它让你的项目更安全、可维护、可部署。
到此这篇关于Python使用dotenv读取环境变量的示例详解的文章就介绍到这了,更多相关Python dotenv读取环境变量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
django框架中ajax的使用及避开CSRF 验证的方式详解
这篇文章主要介绍了django框架中ajax的使用及避开CSRF 验证的方式,结合实例形式分析了Django框架ajax后台交互与排除验证csrf相关操作技巧,需要的朋友可以参考下2019-12-12
Python控制自己的手机摄像头拍照并自动发送到邮箱案例讲解
这篇文章主要介绍了Python控制自己的手机摄像头拍照,并把照片自动发送到邮箱,大概思路是通过opencv调用摄像头拍照保存图像本地用email库构造邮件内容,保存的图像以附件形式插入邮件内容用smtplib库发送邮件到指定邮箱,需要的朋友可以参考下2022-04-04
pandas dataframe rolling移动计算方式
在Pandas中,rolling()方法用于执行移动窗口计算,常用于时间序列数据分析,例如,计算某商品的7天或1个月销售总量,可以通过rolling()轻松实现,该方法的关键参数包括window(窗口大小),min_periods(最小计算周期)2024-09-09


最新评论