python-dotenv
是一个非常实用的 Python 库,它的核心功能是从一个名为 .env
的文件中读取键值对,并将它们加载到操作系统的环境变量中。
在软件开发中,我们经常需要处理一些敏感或可变的配置信息,例如:
- 数据库连接字符串
- API 密钥(如微信、GitHub、天气 API 的密钥)
- 调试开关(
DEBUG=True
或DEBUG=False
) - 第三方服务的用户名和密码
直接将这些信息硬编码在代码中是极其危险且不灵活的做法,主要有以下弊端:
- 安全风险:如果将代码提交到 GitHub 等公共仓库,API 密钥等敏感信息会完全暴露。
- 配置困难:如果需要在开发、测试、生产环境中使用不同的数据库或 API 密钥,就需要频繁修改代码。
- 协作不便:团队中每个成员的本地配置可能都不同,硬编码会导致代码在别人的机器上无法运行。
python-dotenv
完美地解决了这些问题。它倡导将配置与代码分离的原则,让你能够:
- 保护敏感信息:将密钥等保存在本地的
.env
文件中,并将.env
文件添加到.gitignore
,从而避免将其提交到版本控制系统。 - 环境隔离:为不同的环境(开发、生产)提供不同的
.env
文件,实现轻松切换。 - 代码整洁:代码中只引用环境变量,而不需要关心具体的值是什么。
核心用法:一个完整实例
假设我们正在开发一个需要连接数据库和调用天气 API 的应用。
第 1 步:安装 python-dotenv
pip install python-dotenv
第 2 步:在项目根目录创建 .env
文件
创建一个名为 .env
的文本文件,并按 KEY=VALUE
的格式写入你的配置。
# .env file
# 这是一个注释,会被忽略
DATABASE_URL="postgresql://user:password@localhost/mydatabase"
API_KEY="a_very_secret_api_key_12345"
DEBUG="True"
APP_NAME="My Awesome App"
第 3 步:将 .env
添加到 .gitignore
(至关重要!)
为了防止敏感信息泄露,必须将 .env
文件排除在版本控制之外。打开或创建 .gitignore
文件,添加以下内容:
# .gitignore
# 忽略环境变量文件
.env
# 其他常见的忽略项
__pycache__/
*.pyc
venv/
.idea/
这一步是保证项目安全的关键!
第 4 步:在 Python 代码中加载和使用环境变量
创建一个 Python 文件(例如 main.py
),在代码的最开始调用 load_dotenv()
。
# main.py
import os
from dotenv import load_dotenv
# 在程序启动时,立即加载 .env 文件中的环境变量
# 它会自动查找当前目录或父目录中的 .env 文件
load_dotenv()
# 现在,可以使用 os.getenv() 来获取这些变量
db_url = os.getenv("DATABASE_URL")
api_key = os.getenv("API_KEY")
app_name = os.getenv("APP_NAME")
# 注意:os.getenv() 返回的是字符串。对于布尔值或数字,需要手动转换。
is_debug = os.getenv("DEBUG") == "True"
print(f"应用名称: {app_name}")
print(f"数据库连接: {db_url}")
print(f"API 密钥: {api_key}")
if is_debug:
print("应用正在以调试模式运行。")
else:
print("应用正在以生产模式运行。")
# 如果环境变量不存在,os.getenv() 会返回 None
non_existent_var = os.getenv("A_VARIABLE_THAT_DOES_NOT_EXIST")
print(f"不存在的变量: {non_existent_var}")
# 输出: 不存在的变量: None
运行结果:
当你执行 python main.py
时,输出将是:
应用名称: My Awesome App
数据库连接: postgresql://user:password@localhost/mydatabase
API 密钥: a_very_secret_api_key_12345
应用正在以调试模式运行。
不存在的变量: None
与 Web 框架(如 Flask)的集成
python-dotenv
与 Flask 的集成非常顺畅,甚至可以说是自动化的。
当你安装了 python-dotenv
后,Flask 的 flask run
命令会自动检测到它,并在启动应用前自动加载 .env
和 .flaskenv
文件。
这意味着,在 Flask 项目中,你通常不需要在代码里手动写 load_dotenv()
。
Flask 项目实例:
-
安装依赖:
pip install Flask python-dotenv
-
创建
.flaskenv
或.env
文件:
(Flask 优先加载.flaskenv
,然后是.env
)# .flaskenv FLASK_APP=app.py FLASK_DEBUG=1 SECRET_KEY="a_strong_secret_key_for_sessions"
-
创建应用
app.py
:# app.py import os from flask import Flask app = Flask(__name__) # Flask 会自动加载 .flaskenv 文件,所以我们直接用 os.getenv() 即可 # 无需在这里写 load_dotenv() app.config['SECRET_KEY'] = os.getenv('SECRET_KEY') @app.route('/') def index(): # 检查调试模式是否开启 if app.debug: return f"Hello! The app is in debug mode. Secret key is set: {bool(app.config.get('SECRET_KEY'))}" else: return "Hello from production mode!"
-
运行应用:
你只需要在终端运行flask run
,Flask 会自动读取.flaskenv
,设置FLASK_APP
和FLASK_DEBUG
,并启动服务器。
高级用法和技巧
-
指定
.env
文件路径:如果你的.env
文件不在项目根目录,可以指定路径。from dotenv import load_dotenv from pathlib import Path env_path = Path('.') / 'config' / '.env.local' load_dotenv(dotenv_path=env_path)
-
覆盖已存在的环境变量:默认情况下,
load_dotenv()
不会覆盖系统中已经存在的同名环境变量。如果你希望.env
文件中的值优先,可以设置override=True
。load_dotenv(override=True)
总结
- 核心目的:将配置(特别是敏感信息)与代码分离,提高安全性和灵活性。
- 工作方式:从
.env
文件读取键值对,并加载到os.environ
中。 - 基本步骤:
pip install python-dotenv
-> 创建.env
文件 -> 在代码开头调用load_dotenv()
-> 使用os.getenv()
获取值。 - 黄金法则:永远,永远要把
.env
文件添加到.gitignore
中! - 框架集成:在 Flask 等现代框架中,通常是自动集成的,无需手动加载。