
UV 本身不修改虚拟环境的激活脚本来持久注入环境变量,而是通过 uv run --env-file 或 UV_ENV_FILE 环境变量机制,在运行时动态加载 .env 文件,兼顾安全性、可复现性与跨平台一致性。
uv 本身不修改虚拟环境的激活脚本来持久注入环境变量,而是通过 uv run --env-file 或 uv_env_file 环境变量机制,在运行时动态加载 .env 文件,兼顾安全性、可复现性与跨平台一致性。
在 Python 开发中,环境变量(如 DATABASE_URL、SECRET_KEY、DEBUG=True)是配置敏感信息和运行时行为的关键手段。但传统做法——手动编辑 .venv/Scripts/activate(Windows)或 .venv/bin/activate(Linux/macOS)——不仅破坏虚拟环境的可移植性,还极易因版本更新、跨平台差异或 CI/CD 流水线执行而失效。UV 作为现代 Python 工具链的核心组件,刻意规避了“污染激活脚本”的反模式,转而提供更可靠、声明式、符合 12-Factor 应用原则的环境变量管理方案。
✅ 正确做法:使用 uv run + .env 文件(推荐)
UV 的 run 子命令专为“在受控环境中执行命令”而设计,它会自动识别当前项目(依据 pyproject.toml 或 .venv 目录),并支持通过 --env-file 参数加载环境变量:
# 创建标准 .env 文件(明文,切勿提交至 Git) echo "DATABASE_URL=sqlite:///dev.db" > .env echo "DEBUG=true" >> .env echo "LOG_LEVEL=INFO" >> .env # 运行脚本时自动注入变量 uv run python main.py # 等价于:uv run --env-file=.env python main.py
? 提示:
.env是默认文件名,UV 会自动查找;你也可显式指定:uv run --env-file=.env.production python app.py
✅ 全局生效:设置 UV_ENV_FILE 环境变量
若希望所有 uv run 命令统一加载某份环境配置(例如团队共享的开发模板),可提前设置环境变量:
# Linux/macOS(写入 ~/.zshrc 或 ~/.bashrc) export UV_ENV_FILE="$PWD/.env.local" # Windows(PowerShell) $env:UV_ENV_FILE = "$PWD\.env.local" # 后续任意 uv run 均自动加载该文件 uv run flask run
此方式特别适用于 Docker 构建、CI 流水线或本地开发统一配置场景,避免重复传递 --env-file 参数。
⚠️ 注意事项与最佳实践
-
不修改激活脚本:
.venv/Scripts/activate或.venv/bin/activate是 UV 自动生成的底层工具链文件,手动编辑不仅会被覆盖,还违反虚拟环境“隔离性”设计初衷。 -
.env文件需被忽略:务必在.gitignore中加入:# 环境变量文件(含敏感信息) .env .env.*
-
优先级规则:UV 加载顺序为:命令行
--env>--env-file指定文件 >UV_ENV_FILE指向文件 > 系统环境变量。冲突时前者覆盖后者。 -
安全增强(生产环境):对于生产部署,建议结合
uvx或直接使用uv run配合外部 secrets 管理器(如 HashiCorp Vault、AWS Secrets Manager),而非依赖本地.env文件。 -
验证是否生效:可在脚本中快速调试:
# debug_env.py import os print("DEBUG =", os.getenv("DEBUG")) print("DATABASE_URL =", os.getenv("DATABASE_URL"))执行
uv run python debug_env.py查看输出。
? 补充:与 uv pip 和 uv venv 的关系
需要明确的是:uv pip install 和 uv venv 本身不处理运行时环境变量——它们只负责依赖安装与解释器隔离。环境变量属于“应用执行上下文”,因此必须由 uv run(或你自己的启动器)承载。这也是 UV 设计哲学的体现:职责分离,各司其职——venv 管环境、pip 管包、run 管执行。
综上,UV 并非“不支持”环境变量,而是以更现代、更工程化的方式支持它:拒绝隐式副作用,拥抱显式声明;放弃手动 hack,转向标准化协议。掌握 uv run --env-file 这一核心模式,你将获得可复现、易协作、零维护成本的环境配置体验——这正是高效 Python 工程化的关键一步。

















