news 2026/3/7 14:26:55

python环境搭建 (十一) 在不同环境中使用python-dotenv

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
python环境搭建 (十一) 在不同环境中使用python-dotenv

你想知道如何用python-dotenv适配开发、测试、生产等不同环境的配置管理,核心思路是为每个环境单独创建专属的.env配置文件(比如.env.dev.env.test.env.prod),再通过指定加载文件环境变量标记环境的方式,让代码自动加载对应环境的配置,既保证各环境配置隔离,又不用修改核心代码。

下面讲两种最常用的方案,方案一(指定文件加载)简单直观,适合本地开发/小型项目;方案二(环境变量自动切换)更规范,适合团队协作/线上部署,是行业最佳实践,建议重点掌握。

前置准备

  1. 确保已安装python-dotenv(任意稳定版均可,包括你之前的 1.2.1):

    pipinstallpython-dotenv>=1.0.0
  2. 项目根目录为每个环境创建独立的配置文件,遵循统一命名规范(推荐.env.环境名),示例文件结构:

    你的项目/ ├── .env.dev # 开发环境(本地调试,数据库用本地、调试模式开启) ├── .env.test # 测试环境(测试服务器,数据库用测试库、日志级别INFO) ├── .env.prod # 生产环境(线上服务器,数据库用线上、调试模式关闭,密钥用正式的) ├── .gitignore # 关键:忽略所有.env配置文件,防止敏感信息提交 └── main.py # 项目入口文件(加载配置的核心逻辑写在这里)
  3. 各配置文件按KEY=VALUE写专属配置,相同配置键名保持一致,值随环境变化,示例:

    • .env.dev(开发环境):
      # 开发环境-本地数据库 DB_URL=mysql+pymysql://root:123456@localhost:3306/dev_db # 开启调试模式 DEBUG=True # 日志级别-详细 LOG_LEVEL=DEBUG # 本地接口地址 API_BASE_URL=http://127.0.0.1:8000
    • .env.prod(生产环境):
      # 生产环境-线上数据库 DB_URL=mysql+pymysql://prod_user:ProdPass123@prod-db:3306/prod_db # 关闭调试模式(必关!防止泄露信息) DEBUG=False # 日志级别-精简 LOG_LEVEL=WARNING # 线上接口地址 API_BASE_URL=https://api.xxx.com
    • .env.test(测试环境):配置介于开发和生产之间,用测试库即可。
  4. 完善.gitignore忽略所有真实配置文件,只保留示例文件(可选):

    # 忽略所有环境的配置文件 .env .env.* # 可选:保留配置示例,给团队成员参考格式(无真实值) !.env.example

    可创建.env.example作为模板,只写键不写值:

    # 配置示例:复制为 .env.xxx 并填写对应环境的真实值 DB_URL= DEBUG= LOG_LEVEL= API_BASE_URL=

方案一:手动指定文件加载(简单直观,适合本地开发)

核心是通过load_dotenv()dotenv_path参数,直接指定要加载的环境配置文件,想切换环境时,只需修改这一行的文件名称,适合本地调试、单人开发。

核心代码(main.py)

# 项目入口文件:main.pyfromdotenvimportload_dotenvimportos# 核心:指定加载的环境配置文件,切换环境只改这里!# 开发环境:load_dotenv(dotenv_path=".env.dev")# 测试环境:load_dotenv(dotenv_path=".env.test")# 生产环境:load_dotenv(dotenv_path=".env.prod")load_dotenv(dotenv_path=".env.dev")# 默认加载开发环境# 后续读取配置的逻辑完全不变,所有环境通用# 读取并转换配置(统一处理类型,避免各环境重复写)DB_URL=os.environ.get("DB_URL")DEBUG=os.environ.get("DEBUG")=="True"# 字符串转布尔LOG_LEVEL=os.environ.get("LOG_LEVEL","INFO")# 设默认值API_BASE_URL=os.environ.get("API_BASE_URL")# 测试配置加载if__name__=="__main__":print(f"当前环境:开发环境")print(f"数据库地址:{DB_URL}")print(f"调试模式:{DEBUG}")print(f"日志级别:{LOG_LEVEL}")

切换环境

只需修改load_dotenv(dotenv_path="xxx")中的文件路径,比如要切生产环境,改为:

load_dotenv(dotenv_path=".env.prod")

运行代码后,会自动加载生产环境的所有配置,无需修改其他读取配置的代码


方案二:通过系统环境变量自动切换(行业最佳实践,适合团队/部署)

方案一需要手动改代码,不适合线上部署(总不能改代码切环境),更规范的方式是:在系统/部署环境中设置一个「环境标记变量」(比如ENV=prodENV=dev),代码中先读取这个标记,再自动加载对应名称的.env文件,实现「无代码修改,仅通过环境变量切换环境」。

这是企业开发的标准做法,支持本地开发、服务器部署、Docker容器等所有场景。

核心思路

  1. 定义环境标记变量:约定一个固定键名(比如ENVFLASK_ENVFASTAPI_ENV),值为环境名(dev/test/prod);
  2. 代码中先读取这个标记,判断当前是哪个环境;
  3. 根据环境名拼接对应配置文件路径(比如ENV=prod→ 加载.env.prod);
  4. 统一加载配置,后续读取逻辑不变。

核心代码(main.py)

封装了自动加载+配置统一转换的逻辑,可直接复用,后续新增环境只需加.env.新环境文件,无需改代码:

# 项目入口文件:main.pyfromdotenvimportload_dotenvimportosimportsysdefload_env():"""加载对应环境的配置文件,封装为函数,方便项目各处调用"""# 1. 读取系统环境中的「环境标记」,默认加载开发环境(本地调试友好)# 约定标记键名为 ENV,可自定义(比如 PROJECT_ENV)env=os.environ.get("ENV","dev")# 无标记时,默认dev# 2. 拼接配置文件路径(.env.dev/.env.test/.env.prod)dotenv_path=f".env.{env}"# 3. 检查配置文件是否存在,不存在则报错(避免加载空配置)ifnotos.path.exists(dotenv_path):print(f"错误:配置文件{dotenv_path}不存在!",file=sys.stderr)sys.exit(1)# 退出程序,避免配置缺失导致运行错误# 4. 加载配置文件load_dotenv(dotenv_path=dotenv_path,override=True)print(f"✅ 成功加载{env}环境配置:{dotenv_path}")# 项目启动时,最先执行配置加载(必须在所有业务代码之前)load_env()# 统一读取并转换配置(所有环境通用,一次封装,处处使用)# 注意:所有配置都做「非空校验+类型转换+默认值」,保证鲁棒性DB_URL=os.environ.get("DB_URL")ifnotDB_URL:raiseValueError("配置错误:DB_URL 未设置!")# 核心配置缺失直接报错DEBUG=os.environ.get("DEBUG","False")=="True"# 默认关闭调试LOG_LEVEL=os.environ.get("LOG_LEVEL","INFO").upper()# 统一大写(DEBUG/INFO/WARNING)API_BASE_URL=os.environ.get("API_BASE_URL","http://127.0.0.1:8000")# 测试配置if__name__=="__main__":print(f"数据库地址:{DB_URL}")print(f"调试模式:{DEBUG}")print(f"日志级别:{LOG_LEVEL}")print(f"接口地址:{API_BASE_URL}")

关键:如何设置「环境标记变量 ENV」?

不同运行环境(本地终端、Windows/Mac、服务器、Docker)的设置方式不同,核心是在运行Python代码前,让系统能读取到ENV变量,下面讲最常用的场景:

场景1:本地开发(终端运行,Mac/Linux/Windows PowerShell)

在运行python main.py前,先在终端临时设置ENV变量,仅当前终端会话有效,关闭终端后失效(适合本地调试不同环境):

# Mac/Linux/Windows PowerShell - 设为开发环境(默认,可省略)exportENV=dev&&python main.py# 设为测试环境exportENV=test&&python main.py# 设为生产环境exportENV=prod&&python main.py

Windows CMD 终端语法略有不同:

# Windows CMD - 设为生产环境 set ENV=prod && python main.py
场景2:本地永久设置(不想每次终端都输,适合个人开发)

可将ENV=dev写入系统环境变量,实现永久生效,不同系统设置方式:

  • Mac/Linux:编辑~/.bashrc~/.zshrc,添加一行export ENV=dev,执行source ~/.zshrc生效;
  • Windows:此电脑 → 属性 → 高级系统设置 → 环境变量 → 新建系统变量,键ENV,值dev,重启终端生效。
场景3:线上服务器部署(Linux/云服务器)

在服务器的启动脚本(比如start.sh)中设置ENV变量,启动项目时执行脚本即可,示例start.sh

#!/bin/bash# 服务器启动脚本:设置为生产环境exportENV=prod# 启动Python项目(以FastAPI为例,其他项目同理)uvicorn main:app --host0.0.0.0 --port80

赋予脚本执行权限并运行:

chmod+x start.sh ./start.sh
场景4:Docker 部署(最常用的容器化方式)

Dockerfiledocker-compose.yml中设置ENV变量,容器启动时自动加载,示例docker-compose.yml

version:'3'services:app:build:.ports:-"80:80"# 设置环境标记:生产环境environment:-ENV=prodrestart:always

方案三:生产环境优化(不加载 .env 文件,直接用系统环境变量)

线上生产环境的最佳实践是:不把.env.prod文件放到服务器(避免文件泄露),而是直接在服务器/容器中设置所有配置变量(比如 DB_URL、DEBUG 等),此时代码中只需跳过.env加载逻辑,直接读取系统环境变量即可。

基于方案二的代码,只需做简单修改,就能实现生产环境自动跳过 .env 加载,更安全:

defload_env():env=os.environ.get("ENV","dev")# 生产环境:不加载.env文件,直接读取系统环境变量ifenv=="prod":print("✅ 生产环境:直接读取系统环境变量")return# 非生产环境(dev/test):加载对应.env文件dotenv_path=f".env.{env}"ifnotos.path.exists(dotenv_path):print(f"错误:配置文件{dotenv_path}不存在!",file=sys.stderr)sys.exit(1)load_dotenv(dotenv_path=dotenv_path,override=True)print(f"✅ 成功加载{env}环境配置:{dotenv_path}")

这样生产环境无需上传.env.prod,所有配置直接在服务器/Docker中设置,彻底避免敏感配置文件泄露。


补充:配置的统一管理(进阶技巧)

如果项目较大,配置分散在各处会不好维护,可将配置读取逻辑封装为单独的配置文件(比如settings.py),项目所有模块都从这里导入配置,实现单一入口

示例:创建 settings.py(配置统一管理)

# settings.py:配置统一管理文件,项目所有模块都从这里导入fromdotenvimportload_dotenvimportosimportsys# 加载环境配置(复用之前的load_env函数)defload_env():env=os.environ.get("ENV","dev")ifenv=="prod":print("✅ 生产环境:读取系统环境变量")returndotenv_path=f".env.{env}"ifnotos.path.exists(dotenv_path):print(f"错误:{dotenv_path}不存在",file=sys.stderr)sys.exit(1)load_dotenv(dotenv_path=dotenv_path,override=True)print(f"✅ 加载{env}环境配置:{dotenv_path}")load_env()# 核心配置(非空校验+类型转换+默认值)# 数据库配置DB_URL=os.environ.get("DB_URL")ifnotDB_URL:raiseValueError("配置缺失:DB_URL 必须设置!")# 服务配置DEBUG=os.environ.get("DEBUG","False")=="True"LOG_LEVEL=os.environ.get("LOG_LEVEL","INFO").upper()API_BASE_URL=os.environ.get("API_BASE_URL","http://127.0.0.1:8000")# 服务器配置HOST=os.environ.get("HOST","0.0.0.0")PORT=int(os.environ.get("PORT",8000))

项目中其他模块导入使用(简单便捷)

# main.py / 其他业务文件fromsettingsimportDB_URL,DEBUG,HOST,PORT# 直接使用配置,无需再处理加载/转换print(f"启动服务:{HOST}:{PORT},调试模式:{DEBUG}")print(f"数据库连接:{DB_URL}")# FastAPI示例fromfastapiimportFastAPI app=FastAPI(debug=DEBUG)if__name__=="__main__":importuvicorn uvicorn.run(app,host=HOST,port=PORT)

核心总结(不同环境使用 python-dotenv 的关键)

  1. 配置隔离:为每个环境创建专属配置文件.env.dev/.env.test/.env.prod相同键名,不同值,保证环境隔离;
  2. 两种切换方式
    • 本地开发用方案一:直接指定dotenv_path加载文件,简单直观;
    • 团队/部署用方案二:设置系统环境标记ENV,代码自动加载对应配置,无代码修改;
  3. 生产环境最佳实践不使用.env.prod文件,直接在服务器/容器中设置系统环境变量,代码中跳过.env加载,更安全;
  4. 配置统一管理:封装settings.py,将加载、转换、校验逻辑集中,项目所有模块统一导入,避免重复代码;
  5. 必做操作:将.env/.env.*加入.gitignore,只保留.env.example模板,防止敏感配置泄露。

这种方式适配所有Python项目(FastAPI/Flask/Django/爬虫等),是行业通用的环境配置管理方案,既灵活又规范。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/6 18:10:23

一文读懂精髓!提示工程架构师的提示测试自动化框架设计

一文读懂精髓!提示工程架构师的提示测试自动化框架设计 一、引言:为什么你的提示需要“自动化测试”? 1.1 一个让开发者崩溃的场景 你有没有过这样的经历? 为了优化客服机器人的提示,你花了3天调整措辞,把“请提供订单号”改成“麻烦告诉我你的订单编号哦~”,结果上线…

作者头像 李华
网站建设 2026/3/3 19:32:21

从2小时录音快速找重点?「寻音捉影·侠客行」实战测评

从2小时录音快速找重点?「寻音捉影侠客行」实战测评 在信息过载的今天,你是否也经历过这样的场景:会议录音长达127分钟,却只为了确认老板说的那句“下季度预算翻倍”;采访素材堆满硬盘,可关键证词藏在哪一…

作者头像 李华
网站建设 2026/3/5 14:07:24

ANIMATEDIFF PRO实战教程:电影预告片风格——黑场转场+字幕叠加技巧

ANIMATEDIFF PRO实战教程:电影预告片风格——黑场转场字幕叠加技巧 1. 为什么你需要这个教程? 你是不是也试过用AI生成视频,结果导出的片段像PPT翻页一样生硬?没有黑场过渡、没有字幕节奏、更谈不上预告片那种“心跳加速”的张力…

作者头像 李华
网站建设 2026/3/6 11:12:15

ChatTTS辅助创作:帮助作家预听小说朗读效果

ChatTTS辅助创作:帮助作家预听小说朗读效果 1. 为什么作家需要“听见”自己的文字? 你有没有写完一章小说后,反复读了三遍,还是不确定这段对话听起来自然不自然? 有没有改了十次人物台词,却始终拿不准“这…

作者头像 李华
网站建设 2026/3/6 9:01:19

会议纪要神器:寻音捉影·侠客行关键词定位实测

会议纪要神器:寻音捉影侠客行关键词定位实测 在整理一场两小时的项目复盘会议录音时,你是否曾反复拖动进度条,只为找到老板说“下周上线”的那12秒?是否在几十段客户访谈音频里,花掉整个下午寻找一句“价格可以再谈”…

作者头像 李华
网站建设 2026/2/26 12:01:16

LLaVA-v1.6-7B开发者指南:Ollama中加载、提问、调试全流程详解

LLaVA-v1.6-7B开发者指南:Ollama中加载、提问、调试全流程详解 1. 为什么LLaVA-v1.6-7B值得你花10分钟上手 你有没有试过这样一种体验:把一张商品照片拖进对话框,直接问“这个包的材质和价格区间是多少?”——不用写代码、不用配…

作者头像 李华