Python虚拟环境通常或经常可以移动

453 阅读3分钟

Python 虚拟环境有各种神奇的方式。它们被透明地添加到sys.path只要程序使用 venv 的 Python(通常是某个系统版本的 Python 的符号链接),就可以在它们之外,这是两个例子。所有这些魔法都是由venv(cf)根部的一个pyvenv.cfg 文件触发的。这个pyvenv.cfg 的内容非常少,尤其是它们没有命名venv根部的位置。

例如,这里有一个pyvenv.cfg。

home = /usr/bin
include-system-site-packages = false
version = 3.10.5

事实上,这是我的Fedora 36桌面上不少于6个venv的pyvenv.cfg(这些都是通过pipx管理的,但是pipx创建了正常的venv)。 所有的pyvenv.cfg文件都有相同的内容,因为它们都使用相同的Python版本和一般设置。

由于 pyvenv.cfg 和虚拟环境的其他部分不包含任何绝对路径,所以不 "知道 "它们应该在哪里,所以有可能在文件系统上移动 venvs。作为一个推论,有可能将一个 venv 复制到不同的系统中 (在不同的文件系统位置或相同的位置),前提是该系统有相同版本的 Python,如果你在两个系统上使用相同的 Linux 发行版,通常是这样的。这在venv 模块文档中似乎没有明确的记载,而且有可能你安装的某些 Python 模块确实需要绝对路径,而不是可移动的,但这似乎是普遍正确的。

如果你使用 pipx,这里有一个注意事项,因为 pipx 会在 venv 的site-packages 目录中写入一个pipx_shared.pth 文件,该文件确实包含其共享的 Python 东西集合的绝对路径。我相信这是pipx在Python版本升级时出现问题的部分根本原因,可以通过删除这个共享区域并让pipx重建它来解决。

另一个警告来自于像Django这样的系统,它可能会创建标准程序或文件作为其项目设置的一部分。如果你创建了一个 Django venv 并从中启动了一个 Django 项目,Django 会为该项目创建一个 'manage.py' 可执行文件,其中的 venv(当前)的 Python 解释器的绝对路径被刻录在其 '#!' 行中。如果你移动这个 venv,你的manage.py 将(仍然)尝试使用旧 venv 位置的 Python,这将无法工作或得到错误的站点-包路径。

一方面,这在一般情况下是很方便的,而且在虚拟环境的一般设计中也没有阻止它。另一方面,很明显,你可以有各种角落的情况(如pipx和Django所示),所以如果可以的话,最好在他们的最终位置创建你的venvs。如果你确实需要移动venvs(例如它们必须建立在一个目录下并部署在另一个目录下),你可能想测试一下结果,并扫描一下刻录在绝对路径上的东西。

(当我第一次看venvs和sys.path时,我注意到了这个pyvenv.cfg的行为,但我当时并没有仔细研究它。像往常一样,写一篇关于这个问题的文章使我比开始之前更了解情况)。