坏消息:你正在使用venv
, and venv
虚拟环境并不是完全独立的。即使创建时使用--copies
,它复制的只是python
可执行文件本身,而不是标准库,甚至不是(如果您的安装创建了共享libpython
而不是静态的)libpython
;它依赖于系统副本。如果虚拟环境所基于的 Python 安装消失,虚拟环境将会崩溃。How它的破坏会根据它的创建方式而有所不同。例如,如果您使用以下命令创建它:
python3 -mvenv path/to/venv
when python3
表示Python 3.7,然后替换python3
使用 Python 3.8,那么您可以使用以下命令修复新版本的虚拟环境:
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
然后它就完全损坏了(至少按照记录),the --upgrade switch https://docs.python.org/3/library/venv.html#creating-virtual-environments仅当 Python 就地升级时才被记录为可用于升级;因为新的Python不会被命名python3.7
,无法就地升级。也就是说,--upgrade
由于前面提到的每个次要版本,实际上只有在升级微版本(从 3.7.1 到 3.7.2 等)时才能正常工作lib/pythonX.Y
目录,因此无论哪种方式,您最好从头开始创建一个新的虚拟环境。
需要明确的是,第三方virtualenv package https://virtualenv.pypa.io/en/latest/userguide/没有这个限制当且仅当系统Python安装静态链接libpython
。奇怪的是,虽然--always-copy
标志将使它复制主二进制文件和标准库模块,它不会导致libpython
本身(解释器核心)被复制,所以如果主二进制文件依赖于系统副本libpython.so
,然后删除系统副本会破坏虚拟环境。If你确实用过--always-copy
and your 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.7
, libpython3.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