删除和/或更新系统的 Python 时对虚拟环境的影响



为清楚起见,编辑:这个问题指的是venv,它经常与virtualenv混淆。

删除系统的 Python 安装的后果是什么,该安装是用于使用venv在系统上创建虚拟环境的源?

最终,我想做的是删除 3.7 安装并在发布时安装 3.8,但我不确定虚拟环境与系统环境的绑定程度如何。

提出此问题时可能相关的一些系统详细信息:

  • OS = Red Hat Enterprise Linux 7
  • 3.7 从 Python.org 的源代码安装,而不是yum 存储库中的rh-Pythonx.x包。
  • Python 3.7 安装到默认位置,/usr/local/bin/python3.7
  • /usr/local/bin/python3是指向/usr/local/bin/python3.7的链接

鉴于上述细节,我的印象是Python 3.8将安装到/usr/local/bin/python3.8,然后python3将指向该版本。

虚拟环境是否有足够的内容来成为自己的稳定 3.7 环境?还是它会分崩离析,试图引用不再存在的系统安装?

tl;博士:从不再存在/替换为较新版本的 Python 源创建的所有虚拟环境会发生什么情况?

坏消息:您正在使用venv,并且venv虚拟环境并非完全独立。即使使用--copies创建,它复制的只是python可执行文件本身,而不是标准库,甚至(如果您的安装创建共享libpython而不是静态库)libpython;它依赖于系统副本。如果基于Python安装的虚拟环境消失,虚拟环境将中断。中断方式将根据其创建方式而有所不同。例如,如果您使用以下命令创建它:

python3 -mvenv path/to/venv

python3的意思是 Python 3.7,然后用 Python 3.8 替换python3时,你可以用以下命令修复新版本的虚拟环境:

python3 -mvenv --upgrade path/to/venv

但是您安装的第三方软件包将(实际上)消失(它们将在path/to/venv/lib/python3.7中,但Python 3.8只会在path/to/venv/lib/python3.8中查找),因此您必须重新安装它们。

如果您使用以下命令创建了虚拟环境:

python3.7 -mvenv path/to/venv

然后它完全被破坏了(至少如文档所示),--upgrade开关仅在 Python 就地升级时被记录为用于升级;由于新的 Python 不会被命名为python3.7,因此您无法就地升级。也就是说,由于前面提到的每个次要版本lib/pythonX.Y目录,--upgrade仅在升级微版本(从 3.7.1 到 3.7.2 等)时才能很好地工作,所以无论哪种方式,您最好从头开始创建一个新的虚拟环境。

需要明确的是,第三方virtualenv包没有此限制当且仅当系统Python安装静态链接libpython。奇怪的是,虽然--always-copy标志会让它复制主二进制文件和标准库模块,但它不会导致复制libpython本身(解释器核心),所以如果主二进制依赖于libpython.so的系统副本,那么删除系统副本会破坏虚拟环境。如果您确实使用了--always-copy并且您的python可执行文件静态链接libpython.a(ldd /path/to/python3应该不显示libpython依赖项),那么是的,virtualenv变得更加重量级(在 3.6 的本地测试中,通过适当的开关强制复制,新创建的venv环境为 ~11 MB,而virtualenv环境为 ~48 MB;可悲的是, 我的python动态链接libpython.so,所以它仍然不起作用)虚拟环境,这些虚拟环境应该在删除系统安装的 Python 副本后幸存下来。

无论如何,最好保留您的Python 3.7安装,然后升级到3.8而不删除3.7(你真的很难容纳几十MB的磁盘空间吗?即使您将python3替换为新的 3.8 安装,python3.7libpython3.7m.so.1.0等以及 3.7 标准库的其余部分也将继续存在,供虚拟环境依赖;在最坏的情况下,您可能需要手动更改虚拟环境中的符号链接以指向/path/to/python3.7而不是/path/to/python3以继续使用旧版本(包括所有已安装的第三方软件包)。

尝试保持旧虚拟环境正常工作的替代方法是备份该虚拟环境的已安装状态,将其删除,安装新的 Python,创建一个新的虚拟环境,然后使用备份状态重新安装升级后的虚拟环境中的所有包。例如:

$ source ~/path/to/venv/bin/activate
$ pip freeze > installed_libs.txt
$ deactivate
$ rm -rf ~/path/to/venv
$ ... install new Python/remove old Python ...
$ python3 -mvenv ~/path/to/venv
$ pip install -r installed_libs.txt  # Optionally add --upgrade to install latest, not fixed versions

virtualenv包含 python 二进制文件本身的副本,因此不应发生任何操作。在此处查看更详细的说明

virtualenv 通过为每个程序创建一个完全隔离的虚拟环境来解决此问题。环境只是一个目录,其中包含运行 Python 程序所需的一切的完整副本,包括 python 二进制文件本身的副本、整个 Python 标准库的副本、pip 安装程序的副本,以及(至关重要的)上面提到的站点包目录的副本。当您使用由 virtualenv 工具创建的 pip 副本从 PyPI 安装软件包时,它会将软件包安装到 virtualenv 目录内的站点包目录中。然后,您可以像以前一样在程序中使用它。

编辑(考虑 venv 与 virtualenv):根据venv文档,它可以复制或符号链接二进制文件:

venv 模块支持创建具有自己的站点目录的轻量级"虚拟环境",可以选择与系统站点目录隔离。每个虚拟环境都有自己的 Python 二进制文件(与用于创建此环境的二进制文件的版本匹配),并且可以在其站点目录中拥有自己独立的一组已安装的 Python 包。

最新更新