如何用Python代码实现virtualenv虚拟环境及依赖的动态更新?
Python虚拟环境全流程自动化执行方案
前置准备
先在全局Python环境安装pipreqs:
pip install pipreqs
实现逻辑
- 自动调用pipreqs生成最新的requirements.txt文件
- 通过文件哈希比对判断依赖文件是否变更,输出0/1变更标记
- 自动检测虚拟环境是否存在,结合变更标记判断是否需要安装/更新依赖
- 自动调用虚拟环境的Python解释器运行目标脚本
完整可运行代码
将以下代码保存为项目根目录下的run.py,按需修改开头的配置项即可:
import os import sys import hashlib import subprocess from pathlib import Path # -------------------------- 配置项 可自行修改 -------------------------- VENV_DIR = Path("venv") # 虚拟环境存放目录 REQUIREMENTS_FILE = Path("requirements.txt") # 依赖文件路径 HASH_RECORD_FILE = Path(".requirements_hash") # 哈希记录文件(自动生成) TARGET_SCRIPT = Path("main.py") # 你要运行的实际Python脚本路径 # ---------------------------------------------------------------------- # 1. 调用pipreqs生成最新依赖文件 subprocess.run( [sys.executable, "-m", "pipreqs", ".", "--encoding=utf8", "--force"], check=True, capture_output=True, text=True ) # 2. 计算依赖文件变更标记 def get_file_hash(file_path): if not file_path.exists(): return "" hasher = hashlib.md5() with open(file_path, "rb") as f: for chunk in iter(lambda: f.read(4096), b""): hasher.update(chunk) return hasher.hexdigest() current_hash = get_file_hash(REQUIREMENTS_FILE) old_hash = get_file_hash(HASH_RECORD_FILE) if HASH_RECORD_FILE.exists() else "" change_flag = 1 if current_hash != old_hash else 0 # 3. 适配不同系统的虚拟环境可执行文件路径 if os.name == "nt": pip_path = VENV_DIR / "Scripts" / "pip.exe" python_path = VENV_DIR / "Scripts" / "python.exe" else: pip_path = VENV_DIR / "bin" / "pip" python_path = VENV_DIR / "bin" / "python" venv_exists = VENV_DIR.exists() and pip_path.exists() and python_path.exists() # 4. 虚拟环境和依赖处理 if not venv_exists: # 新建虚拟环境 subprocess.run([sys.executable, "-m", "venv", str(VENV_DIR)], check=True) # 安装依赖 subprocess.run([str(pip_path), "install", "-r", str(REQUIREMENTS_FILE)], check=True) # 更新哈希记录 with open(HASH_RECORD_FILE, "w") as f: f.write(current_hash) else: if change_flag == 1: # 依赖变更,重新安装 subprocess.run([str(pip_path), "install", "-r", str(REQUIREMENTS_FILE)], check=True) # 更新哈希记录 with open(HASH_RECORD_FILE, "w") as f: f.write(current_hash) # 5. 运行目标脚本 subprocess.run([str(python_path), str(TARGET_SCRIPT)], check=True)
使用说明
- 后续每次运行项目,只需执行
python run.py即可自动完成全流程操作 - 如需排除特定文件/目录不被pipreqs扫描,可在pipreqs调用参数中添加
--exclude 目录名/文件名 - 自动生成的
.requirements_hash文件可加入.gitignore,无需提交到代码仓库
内容的提问来源于stack exchange,提问作者AL K
相关产品推荐
相关产品推荐

