第89课:环境变量与配置管理
学习目标
通过本课学习,你将能够:
- 理解什么是环境变量及其在应用程序中的作用
- 使用
os.environ在Python中读取和设置环境变量 - 掌握使用
python-dotenv库管理项目配置文件的最佳实践 - 了解如何为不同环境(开发、测试、生产)管理配置
- 安全地存储和管理敏感配置信息
核心概念
什么是环境变量?
想象环境变量就像是贴在程序外面的便利贴。程序运行时会先看看这些便利贴上写了什么设置,然后根据这些设置来调整自己的行为。这样做的最大好处是配置与代码分离。
# 例如,数据库连接字符串不应该硬编码在代码里
# 不好的做法:
db_connection = "mysql://user:password@localhost/mydb"
# 好的做法:从环境变量读取
import os
db_connection = os.environ.get('DATABASE_URL', 'sqlite:///default.db')
为什么需要环境变量?
- 安全性:敏感信息(API密钥、数据库密码)不暴露在代码仓库中
- 灵活性:同一份代码可以在不同环境(开发、测试、生产)中运行
- 可维护性:配置变更不需要修改代码
dotenv 简介
python-dotenv是一个帮助管理环境变量的库,它允许你将环境变量存储在.env文件中,然后在程序启动时自动加载。
# .env 文件内容示例
DATABASE_URL=postgresql://user:pass@localhost/proddb
SECRET_KEY=my-super-secret-key-123
DEBUG=True
API_KEY=your-api-key-here
代码示例
1. 基础环境变量使用
import os
# 读取环境变量,提供默认值
app_mode = os.environ.get('APP_MODE', 'development')
database_url = os.environ.get('DATABASE_URL')
print(f"当前应用模式: {app_mode}")
print(f"数据库URL: {database_url if database_url else '未设置'}")
# 设置环境变量(仅在当前进程有效)
os.environ['TEMP_VAR'] = 'temporary_value'
print(f"临时变量: {os.environ.get('TEMP_VAR')}")
# 检查关键变量是否存在
required_vars = ['DATABASE_URL', 'SECRET_KEY']
missing_vars = [var for var in required_vars if var not in os.environ]
if missing_vars:
print(f"警告: 以下必需环境变量缺失: {', '.join(missing_vars)}")
print("请在.env文件或系统中设置这些变量。")
2. 使用python-dotenv
# 首先安装: pip install python-dotenv
from dotenv import load_dotenv
import os
from pathlib import Path
# 加载.env文件(自动查找当前目录及上级目录的.env文件)
load_dotenv()
# 或者指定文件路径
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)
# 现在可以直接读取环境变量
app_config = {
'debug': os.getenv('DEBUG', 'False').lower() == 'true',
'database': os.getenv('DATABASE_URL'),
'secret_key': os.getenv('SECRET_KEY'),
'api_key': os.getenv('API_KEY'),
'allowed_origins': os.getenv('ALLOWED_ORIGINS', '').split(',')
}
print("应用配置:")
for key, value in app_config.items():
# 对于敏感信息,只显示是否设置,不显示实际值
if key in ['secret_key', 'api_key', 'database']:
print(f" {key}: {'已设置' if value else '未设置'}")
else:
print(f" {key}: {value}")
3. 多环境配置管理
import os
from dotenv import load_dotenv
import sys
# 根据环境变量决定加载哪个配置文件
environment = os.getenv('APP_ENV', 'development')
# 选择对应的.env文件
env_files = {
'development': '.env.development',
'testing': '.env.testing',
'production': '.env.production'
}
env_file = env_files.get(environment, '.env')
print(f"当前环境: {environment}")
print(f"加载配置文件: {env_file}")
# 加载配置
load_dotenv(dotenv_path=env_file)
# 验证关键配置
def validate_config():
required = ['DATABASE_URL', 'SECRET_KEY']
for var in required:
if not os.getenv(var):
print(f"错误: {var} 在 {environment} 环境中未设置")
return False
return True
if validate_config():
print("✓ 所有必需配置已就绪")
else:
print("✗ 配置验证失败,程序无法启动")
sys.exit(1)
实践练习
练习1:基础环境变量读取
创建一个Python脚本,要求:
- 读取环境变量
GREETING和NAME - 如果
GREETING未设置,使用默认值"Hello" - 如果
NAME未设置,提示用户并退出 - 输出格式化问候语
预期输出示例:
输入:GREETING="Hi", NAME="Alice"
输出:Hi, Alice!
练习2:使用dotenv管理配置
-
创建一个
.env文件,包含以下变量:APP_NAME: 你的应用名称VERSION: 版本号(如1.0.0)MAX_RETRIES: 重试次数(如3)DATABASE_URL: 数据库连接字符串
-
编写脚本读取这些配置并输出应用信息
-
实现配置验证:检查所有变量是否存在且类型正确
练习3:多环境配置切换
设计一个简单的应用配置系统:
- 创建三个环境配置文件:
.env.dev、.env.test、.env.prod - 每个文件设置不同的数据库URL和调试模式
- 编写代码根据命令行参数
--env切换环境 - 添加配置回显功能,显示当前使用的配置(隐藏敏感信息)
常见错误
错误1:将.env文件提交到版本控制
# 错误!将.env文件提交到Git
git add .env
git commit -m "添加配置文件"
# 正确做法:在.gitignore中添加
echo ".env" >> .gitignore
echo ".env.*" >> .gitignore
错误2:硬编码敏感信息
# 危险!将密钥直接写在代码中
API_KEY = "sk-1234567890abcdef"
SECRET = "super-secret-password"
# 应该使用环境变量
import os
API_KEY = os.getenv('API_KEY')
SECRET = os.getenv('SECRET_KEY')
错误3:不处理环境变量缺失情况
# 脆弱!直接访问可能不存在的变量
database_url = os.environ['DATABASE_URL'] # 可能抛出KeyError
# 更健壮:使用get()并提供默认值
database_url = os.environ.get('DATABASE_URL', 'sqlite:///default.db')
# 或者显式检查
if 'DATABASE_URL' not in os.environ:
raise ValueError("DATABASE_URL环境变量必须设置")
错误4:混淆开发和生产配置
# 开发环境使用了生产配置
os.environ['APP_ENV'] = 'production' # 开发时不应该设置
# 应该根据实际情况设置
# 开发时在.env或系统中设置为development
# 部署时由部署脚本或容器设置为production
小结
关键要点回顾:
- 环境变量是外部配置:将配置从代码中分离出来,提高安全性和灵活性
- dotenv简化开发:使用
.env文件管理本地开发配置,避免环境污染 - 敏感信息要保护:API密钥、密码等绝不能提交到代码仓库
- 环境隔离:为开发、测试、生产维护不同的配置
- 防御性编程:始终检查环境变量是否存在,提供合理的默认值或错误提示
最佳实践清单:
- ✓ 永远不要提交
.env文件到版本控制 - ✓ 使用
.env.example文件作为模板(提交到仓库) - ✓ 为所有关键配置提供默认值或清晰的错误提示
- ✓ 在应用程序启动时验证所有必需配置
- ✓ 使用
os.getenv()而不是os.environ[],避免KeyError - ✓ 考虑使用配置类或数据类来结构化管理配置
通过本课学习,你已经掌握了现代Python应用程序配置管理的核心技能。记住,良好的配置管理是构建可维护、安全应用程序的重要基础。
练习编辑器
python
Loading...