python:用 dotenv 管理环境变量&生产环境怎么管理环境变量

文章目录

  • [用 dotenv 管理环境变量](#用 dotenv 管理环境变量)
    • 一、为什么要用环境变量?
      • [1. 初学者最常见的错误](#1. 初学者最常见的错误)
      • [2. 正确的工程思想](#2. 正确的工程思想)
    • [二、dotenv 是什么?](#二、dotenv 是什么?)
      • [1. 定义](#1. 定义)
      • [2. `.env` 文件长什么样?](#2. .env 文件长什么样?)
    • 三、安装与基本用法
      • [1. 安装](#1. 安装)
      • [2. 最基础用法](#2. 最基础用法)
    • [四、dotenv 的核心机制(一定要懂)](#四、dotenv 的核心机制(一定要懂))
      • [1. dotenv 本质做了什么?](#1. dotenv 本质做了什么?)
      • [2. dotenv 加载优先级](#2. dotenv 加载优先级)
    • [五、dotenv + Python 项目标准结构](#五、dotenv + Python 项目标准结构)
    • [六、dotenv + FastAPI / AI 项目实战](#六、dotenv + FastAPI / AI 项目实战)
      • [1. AI 项目(OpenAI / LangChain)](#1. AI 项目(OpenAI / LangChain))
      • [2. FastAPI 中只加载一次(重要)](#2. FastAPI 中只加载一次(重要))
    • [七、dotenv + .gitignore(安全必做)](#七、dotenv + .gitignore(安全必做))
      • [.gitignore 必须包含](#.gitignore 必须包含)
    • [八、常见坑(90% 初学者都会踩)](#八、常见坑(90% 初学者都会踩))
      • [1️⃣ `.env` 不生效](#1️⃣ .env 不生效)
      • [2️⃣ 用了 `os.environ[]` 报错](#2️⃣ 用了 os.environ[] 报错)
      • [3️⃣ `.env` 写了引号](#3️⃣ .env 写了引号)
    • [九、dotenv 和生产环境的关系](#九、dotenv 和生产环境的关系)
  • [`load_dotenv` 加载其他文件](#load_dotenv 加载其他文件)
    • [二、`load_dotenv` 的本质原理(先理解这个)](#二、load_dotenv 的本质原理(先理解这个))
      • [`load_dotenv()` 实际做了什么?](#load_dotenv() 实际做了什么?)
    • 三、最基础用法(你已经会的)
    • [四、加载"别的环境变量文件"的正确方式 ⭐](#四、加载“别的环境变量文件”的正确方式 ⭐)
      • [✅ 方法 1:显式指定文件(最常用)](#✅ 方法 1:显式指定文件(最常用))
      • [✅ 方法 2:根据环境动态加载(推荐)](#✅ 方法 2:根据环境动态加载(推荐))
      • 对应文件
    • [五、加载多个 env 文件(覆盖规则很重要)](#五、加载多个 env 文件(覆盖规则很重要))
    • [六、你很可能会踩的 3 个坑(提前告诉你)](#六、你很可能会踩的 3 个坑(提前告诉你))
      • [❌ 坑 1:变量已经存在,load_dotenv 没效果](#❌ 坑 1:变量已经存在,load_dotenv 没效果)
      • [❌ 坑 2:文件路径不对](#❌ 坑 2:文件路径不对)
      • [❌ 坑 3:以为 dotenv 能"读取系统变量"](#❌ 坑 3:以为 dotenv 能“读取系统变量”)
    • [七、dotenv 和系统环境变量的优先级(非常重要)](#七、dotenv 和系统环境变量的优先级(非常重要))
    • 八、推荐写法(结合你实际)

用 dotenv 管理环境变量

一句话结论
dotenv 不是"高级技巧",而是现代工程的起点。

如果你在代码里见过下面这种写法,却不知道它到底解决了什么问题:

python 复制代码
from dotenv import load_dotenv
import os

load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")

那这篇文章就是为你写的。


一、为什么要用环境变量?

1. 初学者最常见的错误

python 复制代码
OPENAI_API_KEY = "sk-xxxxxxx"

问题有三:

  1. 密钥泄露风险
  2. 无法区分开发 / 测试 / 生产环境
  3. 代码不可复用

一旦 push 到 GitHub,你的 key 就"裸奔"了


2. 正确的工程思想

代码不应该包含任何"环境相关"的信息

包括:

  • 密钥(API Key)
  • 数据库密码
  • 域名
  • 开关配置

这些都应该交给 环境变量


二、dotenv 是什么?

1. 定义

dotenv = 用文件的方式,管理环境变量

它解决的问题是:

本地开发时,没有方便的方式设置环境变量


2. .env 文件长什么样?

env 复制代码
OPENAI_API_KEY=sk-xxxx
DB_HOST=localhost
DB_PORT=5432
DEBUG=true

特点:

  • 不是 Python 代码
  • 不需要引号
  • 一行一个变量

三、安装与基本用法

1. 安装

bash 复制代码
pip install python-dotenv

2. 最基础用法

python 复制代码
from dotenv import load_dotenv
import os

load_dotenv()

api_key = os.getenv("OPENAI_API_KEY")
print(api_key)

👉 load_dotenv() 会:

  • 找到当前目录(或父目录)的 .env
  • 把变量加载进系统环境

四、dotenv 的核心机制(一定要懂)

1. dotenv 本质做了什么?

text 复制代码
.env 文件
    ↓
load_dotenv()
    ↓
os.environ["OPENAI_API_KEY"]

👉 dotenv 只是"帮你设置环境变量",不是配置中心


2. dotenv 加载优先级

默认行为:

  1. 系统环境变量
  2. .env 文件(不会覆盖已有环境变量)
python 复制代码
load_dotenv(override=True)  # 强制覆盖

五、dotenv + Python 项目标准结构

推荐目录结构

text 复制代码
project/
├── app/
│   ├── main.py
│   └── config.py
├── .env
├── .gitignore
└── requirements.txt

config.py(推荐写法)

python 复制代码
from dotenv import load_dotenv
import os

load_dotenv()

class Settings:
    OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
    DEBUG = os.getenv("DEBUG") == "true"

settings = Settings()

使用:

python 复制代码
from app.config import settings

print(settings.OPENAI_API_KEY)

六、dotenv + FastAPI / AI 项目实战

1. AI 项目(OpenAI / LangChain)

env 复制代码
OPENAI_API_KEY=sk-xxx
OPENAI_BASE_URL=https://api.openai.com/v1
python 复制代码
load_dotenv()

client = OpenAI(
    api_key=os.getenv("OPENAI_API_KEY"),
    base_url=os.getenv("OPENAI_BASE_URL"),
)

2. FastAPI 中只加载一次(重要)

❌ 错误写法:

python 复制代码
# 每个文件都 load_dotenv
load_dotenv()

✅ 正确写法:

python 复制代码
# main.py
load_dotenv()

其他文件只用 os.getenv


七、dotenv + .gitignore(安全必做)

.gitignore 必须包含

gitignore 复制代码
.env

否则等于没用 dotenv。


八、常见坑(90% 初学者都会踩)

1️⃣ .env 不生效

检查顺序:

  1. 文件名是不是 .env
  2. 是否在项目根目录
  3. 是否调用了 load_dotenv()

2️⃣ 用了 os.environ[] 报错

python 复制代码
os.environ["OPENAI_API_KEY"]  # KeyError

改用:

python 复制代码
os.getenv("OPENAI_API_KEY")   # None

3️⃣ .env 写了引号

env 复制代码
OPENAI_API_KEY="sk-xxx"

❌ 不推荐

dotenv 会把引号当成内容的一部分


九、dotenv 和生产环境的关系

很重要的一点

dotenv 只用于本地开发

生产环境:

  • Docker
  • k8s
  • 云平台

都应该用:

bash 复制代码
export OPENAI_API_KEY=xxx

dotenv 的作用是:

模拟生产环境变量


这个问题问得非常到位 👍

因为 dotenv 到这里就"该退场了",而很多新手正是卡在「本地能跑,线上一团糟」。

我直接给你一套 生产环境"正确心智模型 + 可落地方案",你照着用就行。


load_dotenv 加载其他文件

load_dotenv() 默认只加载当前目录或父目录里的 .env
但你可以显式指定任何文件路径、甚至加载多个文件。


二、load_dotenv 的本质原理(先理解这个)

load_dotenv() 实际做了什么?

  1. 找到一个 .env 文件

  2. 逐行读取:

    env 复制代码
    KEY=value
  3. 等价执行:

    python 复制代码
    os.environ["KEY"] = "value"

👉 它只是帮你往 os.environ 里塞值


三、最基础用法(你已经会的)

python 复制代码
from dotenv import load_dotenv

load_dotenv()

等价于:

  • 查找 .env
  • 加载成功就结束
  • 找不到也不会报错

四、加载"别的环境变量文件"的正确方式 ⭐

✅ 方法 1:显式指定文件(最常用)

python 复制代码
from dotenv import load_dotenv

load_dotenv(".env.dev")

或绝对路径:

python 复制代码
load_dotenv("/Users/zhangyu/project/.env.prod")

✅ 方法 2:根据环境动态加载(推荐)

python 复制代码
import os
from dotenv import load_dotenv

env = os.getenv("ENV", "development")

if env == "development":
    load_dotenv(".env.dev")
elif env == "test":
    load_dotenv(".env.test")

对应文件

env 复制代码
# .env.dev
OPENAI_API_KEY=dev-key
DEBUG=true
env 复制代码
# .env.test
OPENAI_API_KEY=test-key
DEBUG=false

五、加载多个 env 文件(覆盖规则很重要)

python 复制代码
load_dotenv(".env.base")
load_dotenv(".env.local", override=True)

覆盖规则

参数 说明
override=False(默认) 已存在的不覆盖
override=True 后面的覆盖前面的

👉 后加载的优先级更高


六、你很可能会踩的 3 个坑(提前告诉你)


❌ 坑 1:变量已经存在,load_dotenv 没效果

bash 复制代码
export DEBUG=false
python 复制代码
load_dotenv(".env.dev")

👉 默认不会覆盖

✅ 解决:

python 复制代码
load_dotenv(".env.dev", override=True)

❌ 坑 2:文件路径不对

python 复制代码
load_dotenv(".env.dev")

但你是从别的目录启动:

bash 复制代码
uvicorn app.main:app

👉 当前工作目录不是项目根

✅ 推荐写法:

python 复制代码
from pathlib import Path
from dotenv import load_dotenv

BASE_DIR = Path(__file__).resolve().parent
load_dotenv(BASE_DIR / ".env.dev")

❌ 坑 3:以为 dotenv 能"读取系统变量"

❌ 错误理解:

"load_dotenv 能加载服务器已有环境变量"

👉 不行

只读文件,不读系统

系统变量本来就在 os.environ


七、dotenv 和系统环境变量的优先级(非常重要)

来源 优先级
代码里 os.environ["X"] 最高
系统 / Docker / 云平台
dotenv

👉 dotenv 永远不应该覆盖生产环境


八、推荐写法(结合你实际)

目录结构

复制代码
langchain-fastapi-demo/
├─ app.py
├─ agent_demo.py
├─ .env.dev
├─ .env.example

app.py(推荐)

python 复制代码
import os
from pathlib import Path
from dotenv import load_dotenv

BASE_DIR = Path(__file__).parent

ENV = os.getenv("ENV", "development")

if ENV == "development":
    load_dotenv(BASE_DIR / ".env.dev")
相关推荐
云老大TG:@yunlaoda3602 小时前
如何通过华为云国际站代理商OBS实现数据跨境传输与分发加速?
数据库·华为云·php
Java Fans2 小时前
用PyQt打造带动画、碰撞检测和键盘控制的小游戏
python·计算机外设·pyqt
梓仁沐白2 小时前
CSAPP-Archlab
数据库·windows
深蓝海拓2 小时前
PySide6从0开始学习的笔记(十一) QSS 属性选择器
笔记·python·qt·学习·pyqt
-大头.2 小时前
SQL性能优化与索引策略实战
数据库·sql·性能优化
AAA_bo12 小时前
liunx安装canda、python、nodejs、git,随后部署私有网页内容提取工具--JinaReader全攻略
linux·python·ubuntu·typescript·aigc·python3.11·jina
卓豪终端管理2 小时前
构建主动免疫:终端零日漏洞防护新体系
网络·安全·web安全
HappRobot2 小时前
tcpdump抓包分析
网络·测试工具·wireshark
高洁012 小时前
DNN案例一步步构建深层神经网络(3)
python·深度学习·算法·机器学习·transformer