← 返回题目列表

Python 项目如何管理环境变量和配置?为什么不应该把密钥写进代码?

高频 中等 第 10 / 27 题 更新于 2026/07/31
环境变量配置管理.env密钥安全

简化版

Python 项目应把配置和代码分离,数据库密码、API Key、SECRET_KEY 等敏感信息通过环境变量、配置中心或密钥管理系统注入。.env 可以用于本地开发,但不要把真实密钥提交到仓库;生产环境应使用平台提供的 secret 管理能力。

详细版

常见做法是代码读取环境变量:

import os

DATABASE_URL = os.environ["DATABASE_URL"]
DEBUG = os.getenv("DEBUG", "false").lower() == "true"

本地可用 .env 文件配合 python-dotenv,仓库只提交 .env.example。面试重点是:配置会随环境变化,密钥有泄露风险,配置加载要有默认值、校验和清晰优先级。

完整版教学

一、为什么配置要和代码分离

同一份代码要部署到开发、测试、预发、生产,不同环境的数据库、Redis、日志级别、第三方 Key 都不同。把配置写死会导致改环境就改代码。

代码: 同一份
配置: 随环境变化

配置外置后,镜像或包可以复用,环境差异由部署系统注入。

二、哪些属于敏感配置

数据库密码、JWT 密钥、Flask/Django SECRET_KEY、云厂商 AK/SK、支付密钥、Webhook secret 都属于敏感信息。泄露后可能导致数据和资金风险。

不能提交: real password/token/private key
可以提交: .env.example

仓库历史很难彻底清理,密钥一旦提交就应视为泄露并轮换。

三、环境变量怎么读

os.environ["KEY"] 缺失会抛 KeyError,适合必填配置;os.getenv("KEY", default) 适合有默认值的配置。

SECRET_KEY = os.environ["SECRET_KEY"]
LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO")

必填配置启动时失败,比运行中某个请求才失败更好。

配置错误要尽早失败,密钥缺失不要静默用默认弱值。

四、.env 文件适合什么

.env 适合本地开发,让开发者不必每次手动 export 环境变量。生产不应依赖手工 .env 文件,而应使用容器平台、CI/CD secret、KMS 或配置中心。

.env           -> 本地真实值,不提交
.env.example   -> 示例 key,不含秘密,提交

.gitignore 应忽略真实 .env

五、配置优先级怎么设计

常见优先级是默认配置 < 配置文件 < 环境变量 < 启动参数。越靠后越具体。优先级混乱会让排查非常痛苦。

来源优先级
默认值
配置文件
环境变量
命令行参数最高

项目文档要写清楚最终读取顺序。

六、配置校验为什么重要

环境变量都是字符串,需要转换和校验。端口要转 int,DEBUG 要转 bool,URL 要校验格式。可以使用 Pydantic Settings、dynaconf、environs 等工具。

class Settings(BaseSettings):
    database_url: str
    debug: bool = False

配置校验能在启动阶段发现缺失和类型错误。

七、密钥泄露后的处理

密钥一旦进入 Git 历史、日志、截图或 CI 输出,就要按泄露处理。正确动作是立即吊销旧密钥、生成新密钥、更新部署环境,并排查访问日志。只把提交删掉通常不够,因为历史记录和远端缓存可能还在。

revoke -> rotate -> redeploy -> audit

面试中能说出“轮换”比只说“删除代码里的密钥”更完整。

八、配置加载的可观测性

生产排查时,经常需要知道当前应用读到了哪个环境、哪些非敏感配置生效。可以在启动日志中输出环境名、日志级别、功能开关,但不要输出密码、token、私钥。

safe log: ENV=prod LOG_LEVEL=INFO FEATURE_X=true
unsafe log: DATABASE_PASSWORD=...

配置要可排查,但密钥不能为了排查被打印出来。

九、常见误区与追问

  • 误区:私有仓库提交密钥没关系。 私有仓库也可能泄露,成员和 CI 日志都有风险。
  • 误区:生产可以用默认 SECRET_KEY。 默认弱密钥会导致签名伪造风险。
  • 误区:环境变量都是安全的。 它们也可能被日志、进程信息或错误报告泄露,要谨慎。
  • 追问:本地开发怎么配置? .env + .env.example,真实 .env 不提交。
  • 追问:密钥泄露怎么办? 立即撤销和轮换,清理使用方。
  • 追问:bool 环境变量怎么读? 不能直接 bool("false"),要显式解析字符串。
  • 追问:配置中心有什么价值? 集中管理、多环境、审计、动态更新。

十、加强记忆

配置管理记成“代码不变,配置随环境,秘密不进仓库”。必填配置启动即校验,本地用 .env,生产用 secret 管理,仓库只放 example。能讲清读取、优先级、校验和密钥轮换,才是工程化回答。