在 Ubuntu 中安装 Virtualenv

2025年3月17日 | 阅读 15 分钟

Virtualenv 简介

它是一个用于创建独立 Python 环境的工具。自 Python 3.3 版本以来,virtualenv 的一个子集已通过 **_venv_** 模块被开发到标准库中。该模块并未提供此库的每个命名方面,仅提供了一些更突出的方面。

  • 它不那么可扩展。
  • 它速度较慢。
  • 它无法任意为已安装的 Python 版本创建虚拟环境(也无法自动发现它们)。
  • 它无法通过 pip 升级。
  • 它没有强大的编程 API(定义虚拟环境而不创建它们)。

所描述的常见问题间接涉及到版本、依赖和权限。假设我们有一个软件需要 **_LibFoo_** 版本 1,而另一个软件需要版本 2。我们如何使用这些库?如果我们将所有东西都安装到我们的主机 Python(例如,Python 3.8)中,很容易陷入两个包具有冲突要求的境地。

或者如果我们想安装一个软件并保持原样怎么办?如果软件正常工作,对其库或这些库版本的任何修改都可能破坏软件。如果由于没有修改主机 Python 环境的权限而无法将包安装到全局目录(即 **_site-packages_**)中怎么办?

在所有这些情况下,virtualenv 都可以帮助我们。它创建了一个包含其自己的安装目录的环境,这些目录不与其他任何 virtualenv 环境共享库(也不访问全局安装的库)。

Virtualenv 有一个常用命令

它将在 venv 子目录中建立一个与 virtualenv 类似版本的 Python 虚拟环境。命令行工具有一些标志可以改变工具的行为。要查看完整列表,请务必检查 CLI 标志。

这些工具分两个不同的阶段工作

  • **阶段 1** 识别一个 Python 解释器,用于从中创建虚拟环境(默认情况下,它与 virtualenv 运行的 Python 相同;但是,我们可以通过 **_p_** 选项进行修改)。
  • **阶段 2** 在所描述的(dest)目标位置建立一个虚拟环境;它可以分解为四个不同的子步骤
    • 通过阶段 1 建立一个可以匹配目标 Python 解释器的 Python,
    • 在创建的虚拟环境中引导(安装)种子包(多个 wheel、setuptools 和 pip),
    • 建立文件,突出显示虚拟环境应被版本控制系统忽略。这可以使用 **_no-vcs-ignore_** 选项跳过。
    • 将激活脚本下载到虚拟环境的二进制目录中(这将允许最终用户从多个 shell 激活虚拟环境)。

注意:在我们的 virtualenv 中,Python 与用于创建它的 Python 有效地隔离。

在 Python 中,虚拟环境由两个必需的元素组成:虚拟环境执行的 Python 解释器,以及一个包含虚拟环境中第三方库的文件夹。

它们与几个虚拟环境分离,这意味着对虚拟环境中依赖项的任何修改都不会影响其他虚拟环境依赖项或系统范围的库。因此,我们可以使用不同的 Python 版本以及相同或不同版本的库创建两个或更多虚拟环境。

为什么要使用 Python 虚拟环境?

如果我们在一台设备上拥有多个 Python 项目,这些项目依赖于相同包的不同版本,那么 Python 虚拟环境的使用就成为可能。其他一些定义 Python 虚拟环境基本用例的情况是,如果我们正在生产环境或托管服务器上工作,由于特定要求,我们无法更改系统范围的包。

这些虚拟环境构建了独立的上下文,以隔离不同类型项目所需的依赖项,从而不会与系统范围的包或其他项目冲突。通常,设置任何虚拟环境是分离多个 Python 项目的最佳方法之一,尤其当这些项目具有冲突和不同的依赖项时。

如何使用 Python 虚拟环境?

创建 Python 虚拟环境

首先,我们需要创建一个项目文件夹并在其中建立一个虚拟环境。然后,启动终端窗口,输入以下命令,并按回车键

现在我们需要应用 venv 命令在项目文件夹中建立一个虚拟环境。命令如下

**_重要提示:_**_ 有两个工具可用于设置虚拟环境,venv 和 virtualenv,我们几乎可以互换使用它们。virtualenv 工具支持以前的 Python 版本,需要借助 pip 命令安装。此外,venv 工具用于 Python 3.3 或更高版本,并已添加到 Python 的标准库中,无需安装。_

开启 Python 虚拟环境

我们需要执行以下命令来开启我们在上述步骤中创建的虚拟环境

正如我们所看到的,在开启虚拟环境后,名称会以括号形式出现在终端提示符的开头。执行 `which python` 命令也是确保此虚拟环境正在运行的一种方式。如果执行此命令,它会显示虚拟环境中 Python 解释器的位置。我们可以使用以下命令查看虚拟环境中的位置

值得注意的是,虚拟环境的 Python 版本与用于创建环境的 Python 版本相似。我们可以使用以下命令查看虚拟环境中的 Python 版本

如何在 Python 虚拟环境中安装包?

现在,我们处于一个独立的虚拟环境中,默认情况下只安装了 setup tools 和 pip。让我们通过执行 `pip list` 命令来检查虚拟环境中预安装的包

在我们希望使用 pip 安装软件包之前,我们应该首先将其升级到最新版本。因为我们正在虚拟环境中工作,所以以下命令只升级此环境中的 pip 工具,而不是系统范围或其它虚拟环境中的 pip 工具。

如何重现 Python 虚拟环境?

重现任何虚拟环境是非常常见的。首先,我们需要借助 `pip freeze` 命令列出项目中虚拟环境中安装的每个依赖项,如下所示

使用 `pip freeze` 命令的结果与 `pip list` 命令的结果非常相似。但是,它提供了以精确格式安装的软件包列表,以便使用项目所需的相似软件包版本在环境中进行重现。在下一步中,我们将软件包列表导出到文件 `needs.txt` 中。为此,我们需要运行以下命令

上述命令在当前文件夹中创建 `needs.txt` 文件。这个新创建的文件包含每个包及其相同的版本。要查看此文件的内容,我们可以使用以下命令

Python 的发现

Python 解释器是我们能够创建虚拟环境的最初要求。它会告诉工具我们想要建立什么样的虚拟环境;可以将其视为实现、架构或版本。如果我们在 Python 3.8 版本下安装 virtualenv,virtualenv 默认将创建 3.8 版本的虚拟环境。

通常,已建立的 Python 虚拟环境不是自包含的。一个完整的 Python 包由多个文件组成,因此无法将整个 Python 再次安装到一个新的文件夹中。相反,虚拟环境是简单的 shell,自身包含的内容很少,几乎所有内容都借用自系统 Python。这意味着,如果我们升级系统 Python,我们的虚拟环境可能会损坏,所以我们需要小心。就 Python 系统而言,它的优点是建立虚拟环境可以很快。

这里我们将定义内置机制。CLI 标志 **_python_** 或 **_p_** 允许我们定义一个 Python 规范符,以表示我们想要哪种虚拟环境;该类型可以是

  • 以以下格式识别 Python 实现、架构或版本的规范符
  • Python 解释器的绝对/相对路径

我们有以下限制

  • 版本是一个点分隔的版本号。
  • Python 实现是所有字母字符。
  • 架构是 -32 或 -64。例如
    • python3.8.1 定义了任何具有 3.8.1 版本的 Python 实现。
    • 3 定义了任何具有 3 主版本的 Python 实现。
    • cpython3 定义了具有 3 版本的 CPython 实现。
    • pypy2 定义了一个主版本为 2 且实现为 PyPy 的 python 解释器。

鉴于 virtualenv 规范器将使用以下策略来查找/发现系统可执行文件

  • 在 Windows 上,如果我们查看 Windows 注册表并检查是否看到注册的 Python 实现与规范相同。这与 PEP-514 中规定的预期一致。
  • 尝试在 PATH 环境变量中计算出的文件夹内查找相同的 Python 可执行文件。

创建者

创建者是将虚拟环境配置为参考而不是系统 python 的原因。目前,virtualenv 有两种不同类型的虚拟环境

  • **内置:** 这意味着 virtualenv 可以自行执行创建操作(通过准确了解要创建哪些文件以及需要引用哪些系统文件)。使用内置名称,创建者是此类型初始创建者的别名。
  • **venv:** 它将创建过程关联到 venv 模块,如 PEP 405 中所定义。它仅存在于 Python 3.5 或更高版本的解释器上,并且还存在 virtualenv 应该创建一个进程来调用该模块的缺点。

播种器

播种器将为我们安装一些种子包(一个或多个 wheel、setuptools、pip),使我们能够在创建的虚拟环境中安装额外的 Python 包。目前有两种不同的主要播种机制

  • **pip:** 这种机制将随 virtualenv 捆绑的 pip 用于安装种子包。
    **_重要提示:_**_ 需要创建一个新的子进程来完成此操作,这可能会耗费资源,尤其是在 Windows 上。_
  • **应用程序数据:** 这种机制使用用户应用程序数据目录来创建安装映像。映像只需创建一次,后续的虚拟环境只需将映像复制/链接到其 Python 库路径中即可。这使得除了初始虚拟环境建立之外的所有操作都变得非常快。可以使用环境变量 **_VIRTUALENV_OVERRIDE_APP_DATA_** 来覆盖种子缓存文件系统位置。

轮子

要通过应用程序数据或 pip 机制安装种子包,virtualenv 需要继承目标包的 wheel。这些 wheel 可以从多个位置继承

  • **virtualenv** 开箱即用,为三个种子包(wheel、setuptools、pip)提供了一组嵌入式 wheel。这些与 virtualenv 源文件一起打包,并且仅在升级 virtualenv 时进行修改。不同版本的 Python 需要这些包的不同版本,并且由于 virtualenv 支持大量 Python 版本,因此嵌入式 wheel 的数量大于 3。如果发布了这些嵌入式包的新版本,上游项目(即 virtualenv)会升级它们并发布新版本。因此,定期升级 virtualenv 将升级种子包版本。
  • 尽管如此,最终用户可能无法以类似的速度升级 virtualenv。因此,用户可以通过使用 `upgrade-embed-wheels` 标志来请求升级嵌入式 wheel 列表。如果以这种手动方式执行操作,则 virtualenv 的后续执行将始终应用升级后的嵌入式 wheel。
    如果在过去 14 天内没有进行此类升级,此操作也可以作为后台进程在 virtualenv 自动调用下进行。它只会在升级的 wheels 发布超过 28 天且升级完成至少一小时后才自动开始使用升级的 wheels。
    • 28 天的时间应确保最终用户不会自动拉入包含已知错误的版本,
    • 升级完成一小时后实施,因此集成服务不会在未完成一半时启动新的嵌入式版本。

自动行为可以通过 `no-periodic-update` 配置选项/标志停用。要继承任何包的发布日期,virtualenv 将执行以下操作:

用户可以使用命令行标志 **_extra-search-dir_** 描述一组包含额外 wheel 的本地路径。

查找要应用的 wheel 时,virtualenv 会按以下顺序查找

  • 额外搜索目录
  • 升级的嵌入式 wheel
  • 嵌入式 wheel

捆绑的轮子是以上三者的总和。如果这些位置不包含请求的轮子版本或者设置了下载标志,则将使用 pip download 从索引服务器加载可用的最新版本。

分发嵌入式轮子

有时,自定义发行版希望使用自己的 wheel 版本组进行分发,而不是 PyPI 上的单个 virtualenv 版本。这样做的原因是试图使这些包的系统版本与 virtualenv 应用的版本保持同步。在这种情况下,它们应该修补 **_virtualenv.seed.wheels.embed_** 模块,确保提供 **_get_embed_wheel_** 函数。如果它们希望使用 virtualenv 的测试套件进行验证,则需要 MAX、BUNDLE_SUPPORT 和 BUNDLE_FOLDER 变量。

激活器

激活脚本可用,它们将修改我们的 shell 设置,以确保 Python 虚拟环境中的命令优先于我们的系统路径。例如,如果通过我们的 shell 调用 pip,在激活之前它引用的是系统 Python 的 pip,当执行激活后,它应该引用虚拟环境的 pip。

编程接口

Virtualenv 目前只提供 CLI 级别接口。如果我们要从 Python 内部调用 Python 环境,应该使用方法 **_virtualenv.cli_run_**;它需要一个参数 **_args_**,我们可以像在命令行中一样传递选项。

有一些命令行界面参数可以建立一个虚拟环境

参数

  • **args-** 命令行参数
  • **options-** 传入一个 **_VirtualEnvOptions_** 对象,允许返回解析后的选项
  • **setup_logging-** False 表示使用已注册的处理程序,True 表示配置登录处理程序
  • **env-** 要应用的环境变量

返回值

创建会话对象

建立一个 virtualenv 会话(与 cli_run 类似,但不执行创建)。如果我们想知道虚拟环境会是什么样子但不想建立它,请使用此方法

参数

  • **args-** 命令行参数
  • **options-** 传入一个 **_VirtualEnvOptions_** 对象,允许返回解析后的选项
  • **setup_logging-** False 表示使用已注册的处理程序,True 表示配置登录处理程序
  • **env-** 要应用的环境变量

返回值

创建会话对象

说明虚拟环境的创建会话

  • 属性 **_verbosity_**
    运行的详细程度
  • 属性 **_interpreter_**
    根据此首选解释器建立虚拟环境
  • 属性 **_creator_**
    用于构建虚拟环境的创建者
  • 属性 **_seeder_**
    用于提供种子包(wheel、setuptools、pip)的机制
  • 属性 **_activators_**
    用于生成激活脚本的激活器

CLI 界面

CLI 标志

首先,virtualenv 是一个命令行应用程序。它会更改 shell 中的环境变量以建立一个独立的 Python 环境,因此我们需要任何 shell 来执行它。我们可以输入 virtualenv(应用程序名称),后面跟着可以控制其性质的标志。

每个选项都包含合理的默认值,并且有一个必需的参数,即要建立的虚拟环境的路径/名称。命令行选项的默认值可以通过环境变量或配置文件覆盖。环境变量优先于配置文件的值。

可识别的 virtualenv 选项,以及它们的简短描述和默认值如下所述

virtualenv [选项]

  • --version
    它显示 virtualenv 包版本及其位置并退出。
  • --read-only-app-data
    它以只读模式使用应用程序数据文件夹(写操作将因错误而失败)。
  • --with-traceback
    它在失败时也显示堆栈跟踪 virtualenv 内部。
  • --app-data
    它是一个数据文件夹,通过 virtualenv 作为缓存使用。
  • --upgrade-embed-wheels
    它遇到了手动嵌入式 wheel 更新。
  • --reset-app-data
    它以一个空白的应用程序数据文件夹开始。
  • --verbose, -v
    它增加了详细程度。
  • --quiet, -q
    它降低了详细程度。

创建者选项

  • 创建者
    它可以通过选择 venv、pypy3-win、pypy3-posix、pypy2-win、pypy2-posix、cpython3-win、cpython3-posix、cpython3-mac-framework、cpython2-win、cpython2-posix、cpython2-mac-framework、cpython2-mac-arm-framework 来创建环境。
  • --clear
    它在开始之前删除目标目录(如果可用)(否则,它将覆盖文件)。
  • 目标
    它是建立 virtualenv 的目录。
  • --no-vcs-ignore
    它不在目标目录中建立 VCS 忽略指令。
  • --symlinks
    当符号链接不是环境的默认设置时,它尝试应用符号链接而不是副本。
  • --system-site-packages
    它允许虚拟环境访问系统 site-packages 目录。
  • --always-copy, --copies
  • 即使符号链接是环境的默认设置,它也尝试应用副本而不是符号链接。

播种器选项

  • --seeder
    安装种子包的方法。选择:pip, app-data。
  • --without-pip, --no-seed
    它不安装种子包。
  • --download
    它传递给激活从 PyPI 下载当前 wheel/setuptools/pip。
  • --never-download, --no-download
    它传递给停用从 PyPI 下载当前 wheel/setuptools/pip。
  • --extra-search-dir
    这是一个包含 wheel 的路径,用于扩展内部 wheel 列表。
  • --pip
    它是作为种子安装的 pip 版本:确切、嵌入或捆绑版本。
  • --setuptools
    它是作为种子安装的 setuptools 版本:确切、捆绑或嵌入版本。
  • --wheel
    它是作为种子安装的 wheel 版本:确切、捆绑或嵌入版本。
  • --no-pip
    它不安装 pip。
  • --no-setuptools
    它不安装 setuptools。
  • --no-wheel
    它不安装 wheel。
  • --no-periodic-update
    它可以在定期更新中停用嵌入式 wheel。
  • --symlinks-app-data
    它可以通过 app-data 文件夹链接 Python 包。

激活器选项

  • --activators
    这些是要生成的激活器。默认受支持;选择 python, powershell, nushell, fish, cshell, batch, bash。
  • --prompt
    它为此环境提供了一个替代的提示前缀("." 值表示当前工作目录名称)。

默认值

环境变量

此外,默认值可以通过环境变量指定。设置键从命令行选项获取,如果有多个标志,则首先检测到的获胜。

配置文件

Virtualenv 会查找标准配置文件,即 ini。相同的位置取决于我们正在使用的操作系统,具体取决于平台应用程序配置的定义。当传递 --help 选项时,配置文件位置在输出的末尾提及。设置键从命令行选项获取,其中存在多个标志时,首先检测到的获胜。

扩展功能

Virtualenv 允许通过插件系统扩展内置功能。要添加插件,我们需要

  • 指定一个包含插件代码的 Python 文件,该代码遵循我们所需的接口,
  • 将其安装到虚拟环境中,
  • 将其打包为任何 Python 库。

在 Ubuntu 中安装 virtualenv

Virtualenv 是一个开源的免费工具,用于创建独立的 Python 虚拟环境。它被 Python 开发人员和程序员广泛使用,可以轻松测试其不同的应用程序版本。所有虚拟环境都有自己的 Python 库(与用于创建此环境的二进制版本相同),并且可以在其站点目录中拥有自己独立的已安装 Python 包组。基本的安装工具(如 pip 和 setuptools)可以按预期使用虚拟环境。

步骤 1:先决条件

  • 我们应该有一个活动的 Ubuntu 服务器。
  • 我们应该拥有 root 或 sudo 权限来执行特权命令。
  • 我们的系统中应该有 apt-get 或 apt 实用程序。

步骤 2:更新我们的服务器

首先,我们需要通过运行 **_sudo apt update_** 命令来更新系统中的所有软件包。这将使我们的系统软件包与 Ubuntu 存储库中当前可用的版本同步。

如果需要升级任何系统包,我们可以运行 **_sudo apt upgrade_** 命令。

步骤 3:安装 Python3

在此步骤中,我们将使用 **_sudo apt install python3_** 命令安装 Python3 包。它将下载并安装此包及其所有依赖项。

Install Virtualenv Ubuntu

步骤 4:安装 pip3

我们将使用 **_sudo apt install python-pip3_** 命令安装当前版本的 python 包管理器,因为我们需要 pip3 来获取 virtualenv。

Install Virtualenv Ubuntu

步骤 5:安装 virtualenv

在此步骤中,我们将使用 **_pip3 install virtualenv_** 命令安装 virtualenv。如果使用的是早期版本的 pip,则需要运行 **_pip install virtualenv_** 命令。该命令如下图所示

Install Virtualenv Ubuntu

步骤 6:检查版本

我们需要运行 **_virtualenv --version_** 命令来检查 virtualenv 的安装情况。

Install Virtualenv Ubuntu

步骤 7:建立虚拟环境

安装过程完成后,我们可以使用 **_virtualenv venv_** 命令建立一个虚拟环境。

Install Virtualenv Ubuntu

步骤 8:激活或停用环境

当虚拟环境建立后,可以使用其二进制目录中的脚本来激活或停用它。我们需要运行 **_source venv/bin/activate_** 命令来激活虚拟环境。

我们可以运行 **_deactivate_** 命令来停用虚拟环境。


下一个主题Safari Ubuntu