推荐在自动化脚本中加 --upgrade-deps,它使虚拟环境创建时即升级 pip、setuptools 和 wheel 至最新版,避免因旧版 pip 不兼容新包(如不支持 PEP 660)导致 pip install -r requirements.txt 报错;该参数仅适用于 Python 3.9+。

venv 创建脚本要不要加 --upgrade-deps
加不加取决于你是否需要虚拟环境一创建就自带最新版 pip、setuptools 和 wheel。不加的话,新建的环境用的是 Python 内置的旧版本(比如 Python 3.11.9 自带 pip 23.0.1),可能不兼容较新的包或安装方式。
推荐在自动化脚本里加上:--upgrade-deps,它比单独执行 python -m pip install --upgrade pip 更干净——不会触发额外的 shell 切换或路径问题。
- 加了
--upgrade-deps:创建即升级,一步到位,适合 CI/CD 或一键部署场景 - 没加:后续必须手动或额外命令升级,容易遗漏,尤其在无人值守脚本中会卡在
pip install -r requirements.txt报错(例如因 pip 太老不支持 PEP 660) - 注意:该参数仅在 Python 3.9+ 支持;低于此版本会报错
unrecognized arguments: --upgrade-deps
Windows 下写批处理自动激活并运行 pip 的坑
直接在 .bat 脚本里写 venv\Scripts\activate & pip install -r requirements.txt 是无效的——activate 是一个修改当前 shell 环境的脚本,单独用 & 连接时,pip 实际仍在原环境中执行。
正确做法是用 call 并确保后续命令在同一上下文:
立即学习“Python免费学习笔记(深入)”;
call venv\Scripts\activate.bat pip install --upgrade pip pip install -r requirements.txt
更稳妥的写法是封装成单行调用(避免中途退出):
call venv\Scripts\activate.bat && pip install --upgrade pip && pip install -r requirements.txt
- 别用
start或新窗口执行,会导致环境变量丢失 -
activate.bat必须用call,否则批处理会在 activate 后终止 - Linux/macOS 对应的是
source venv/bin/activate,不能直接放进.sh脚本末尾执行,需用bash -c "source venv/bin/activate && pip install ..."
脚本里如何判断 Python 版本再决定用 python 还是 python3
很多自动化脚本在跨平台时硬写 python -m venv,结果在某些 Linux 发行版(如 Ubuntu)上失败——因为 python 指向 Python 2,而 venv 不支持。
安全做法是显式检查并 fallback:
- 先尝试
python3 -m venv .venv(Python 3.3+ 标准路径) - 失败时再试
py -3 -m venv .venv(Windows 上 py launcher 的可靠写法) - 完全规避歧义:用
python3.11 -m venv .venv(如果你明确依赖某小版本)
不要依赖 which python 或 python --version 的输出做字符串匹配——不同系统输出格式不一致(比如 macOS 可能返回 Python 3.11.9,Ubuntu 返回 Python 3.11.9+),容易误判。
venv 脚本要不要自动删旧环境再重建
要,但得加 --clear,而不是手动 rm -rf .venv 或 rmdir /s .venv。
--clear 的作用是清空已有目录内容并复用文件夹,比删除重建更安全:它保留目录权限、符号链接状态,且避免因进程占用导致删除失败(比如 Windows 下 .venv\Scripts\python.exe 正被 IDE 持有句柄)。
- 推荐组合:
python3 -m venv --clear --upgrade-deps .venv - 如果脚本需幂等执行(比如每次 CI 都跑),这个组合可确保环境干净、依赖最新、无需人工干预
- 注意:
--clear不会删掉.venv目录本身,所以后续source .venv/bin/activate依然有效;而手动删目录后,所有相对路径逻辑都要重新校验
最易被忽略的一点:很多人在脚本里用 if [ -d ".venv" ]; then rm -rf .venv; fi,却忘了某些 CI 环境(如 GitLab Runner)默认以非交互模式运行,rm -rf 遇到只读文件或占用进程会静默失败,表面成功实则残留旧环境——用 --clear 才真正可靠。



















