Python开发中为何优先使用环境变量而非硬编码常量?
环境变量在Python中的实际用法与核心优势
一、为什么环境变量比硬编码常量更优
直接把配置写在代码里(硬编码)看似简单,但实际场景中存在诸多弊端,环境变量的优势主要体现在这几个方面:
- 敏感信息安全:API密钥、密码、令牌这类信息如果硬编码,一旦代码提交到Git等版本库,就会直接泄露。环境变量存储在系统或独立配置文件中,代码里只会读取变量名,不会暴露明文。
- 多环境无缝切换:开发、测试、生产环境的配置(比如API端点、调试开关)不用修改代码,只需要切换对应的环境变量即可,避免频繁改代码引发的错误。
- 配置与代码解耦:配置信息和业务逻辑代码分离,维护时不用在代码中查找各种配置项,统一管理环境变量更高效。
- 运行时灵活调整:对于长期运行的服务(如Web应用),无需重启服务或重新部署,修改环境变量就能实时调整配置,比如临时切换API密钥或调整超时时间。
二、环境变量的使用时机
以下场景优先使用环境变量而非硬编码:
- 所有敏感信息:API密钥、数据库密码、身份令牌、OAuth密钥等
- 跨环境差异的配置:API端点URL、服务地址、日志级别、调试模式开关等
- 需要动态调整的参数:请求超时时间、重试次数、限流阈值等
三、环境变量的正确使用方式
1. 本地开发:使用.env文件(推荐)
借助python-dotenv库,将配置存放在.env文件中,代码加载后即可读取:
- 安装依赖:
pip install python-dotenv - 创建
.env文件(注意添加到.gitignore,避免提交到版本库):
APPLICATION_ID=你的实际AppID APPLICATION_KEYS=你的实际AppKey EXERCISE_END_POINT=https://api.exercise.example.com SHEET_END_POINT=https://api.sheety.example.com AUTHORIZATION_TOKEN=Bearer 你的实际令牌 API_USER=你的用户名 API_PASSWORD=你的密码 GENDER=MALE WEIGHT_KG=92 HEIGHT=176.784 AGE=40
2. 系统层面设置
在终端直接设置(仅当前会话有效):
- Linux/Mac:
export APPLICATION_ID="你的AppID" - Windows(命令行):
set APPLICATION_ID="你的AppID" - Windows(PowerShell):
$env:APPLICATION_ID="你的AppID"
3. 容器/云平台配置
在Docker、Kubernetes或云服务商(如AWS、阿里云)的控制台中配置环境变量,无需在代码中做额外处理,直接读取即可。
四、针对你的代码的优化示例
你的代码中存在硬编码敏感信息的问题,同时错误地在代码中设置环境变量(os.environ['API_USER'] = 'user name'),这和硬编码没有区别。以下是优化后的代码:
import requests from datetime import datetime import os from dotenv import load_dotenv # 加载.env文件中的环境变量 load_dotenv() # 从环境变量读取所有配置,不再硬编码 APPLICATION_ID = os.getenv("APPLICATION_ID") APPLICATION_KEYS = os.getenv("APPLICATION_KEYS") EXERCISE_END_POINT = os.getenv("EXERCISE_END_POINT") SHEET_END_POINT = os.getenv("SHEET_END_POINT") AUTHORIZATION_TOKEN = os.getenv("AUTHORIZATION_TOKEN") GENDER = os.getenv("GENDER") WEIGHT_KG = os.getenv("WEIGHT_KG") HEIGHT = os.getenv("HEIGHT") AGE = os.getenv("AGE") USERNAME = os.getenv("API_USER") PASSWORD = os.getenv("API_PASSWORD") DATE_FORMAT = "%d/%m/%Y" LOCAL_TIME_FORMAT = "%X" headers = { "x-app-id": APPLICATION_ID, "x-app-key": APPLICATION_KEYS, } exercise_input = input("Tell us which exercise you did today?: ") params = { "query": exercise_input, "gender": GENDER, # 修正原代码中gender硬编码为female的问题,统一使用环境变量配置 "weight_kg": WEIGHT_KG, "height_cm": HEIGHT, "age": AGE } # 增加异常处理,方便调试API请求错误 try: response = requests.post(EXERCISE_END_POINT, json=params, headers=headers) response.raise_for_status() result = response.json() except requests.exceptions.RequestException as e: print(f"API请求失败: {e}") exit(1) exercise = result['exercises'][0]['name'].title() duration = result['exercises'][0]['duration_min'] calories = result['exercises'][0]['nf_calories'] print(exercise, duration, calories) date = datetime.now() formatted_date = date.strftime(DATE_FORMAT) time = date.strftime(LOCAL_TIME_FORMAT) para = { 'workout': { 'date': formatted_date, 'time': time, 'exercise': exercise, 'duration': duration, 'calories': calories, } } # Basic Authentication auth = (USERNAME, PASSWORD,) # Bearer Token Authentication bearer_headers = { 'Authorization': AUTHORIZATION_TOKEN, } try: response = requests.post(SHEET_END_POINT, json=para, headers=bearer_headers) response.raise_for_status() result = response.json() print(result) except requests.exceptions.RequestException as e: print(f"提交数据失败: {e}") exit(1)
优化说明
- 移除了所有硬编码的敏感信息,全部通过环境变量读取
- 使用
python-dotenv加载本地配置,本地开发更便捷,同时避免配置泄露 - 增加了API请求的异常处理,便于排查错误
- 修正了原代码中
gender参数硬编码与环境变量GENDER冲突的问题
内容的提问来源于stack exchange,提问作者Anurag Jain
相关产品推荐
相关产品推荐

