通过 pip 安装 Python 软件包时使用 venv 虚拟环境的必要性
为了避免与系统软件包发生冲突, 建议使用 venv 虚拟环境.

在一些 Linux 发行版中, 系统会自带 Python 解释器, 默认的 sys.prefix 以及 sys.exec_prefix/usr/local, 直接安装软件包便会写入这个系统目录下.

系统的包管理器可能会接管一些 Python 软件包的安装, 并通常会将它们安装在系统目录下. 当自己或其他用户前后分别通过 pip 和系统包管理器安装软件包时, 便可能发生冲突 — 比如破坏掉包管理器的安装, 进而导致其无法正常工作. 此外, 包管理器中的 Python 软件包版本可能较为滞后, 对需要使用较新软件包的用户来说并不合适. 因此, 建议使用独立于系统 Python 解释器的 Python 安装 (通常需要自行构建), 或创建 “虚拟环境” (见下文), 再在其中安装自己需要的软件包.

而在 Windows 上, Python 的安装相对独立, 因此一般用户直接将软件包安装到 Python 环境下也并不会有特别的影响. Python 语言的安装器, 默认会将语言 (执行环境) 安装在用户的 %LocalAppData% 下 (笔者也建议这么做). 而 pip 安装软件包时, 默认也是根据 prefix 决定路径, 即 pip 对应 Python 安装的下方. 若用户在安装 Python 时, 将 Python 安装在了一些权限受限的地方 (如 %ProgramFiles% 目录下), 则 pip 会将软件包安装在用户的 %AppData% 中.

另请参见 “在 Windows 上使用 Python - docs.python.org”.

使用 pip 安装 Python 软件包

Python 语言推荐使用 pip 从 PyPI 安装软件包, 同时可以使用 venv (另见后文介绍) 来将不同项目的环境与共享使用的 Python 安装隔绝开来. 笔者这里也不建议使用额外的第三方软件, 以避免引入额外的复杂度.

Python 语言有若干种实现. 为了表述简便, 在无特殊说明时, 下文中的 Python 在指代语言本身外, 均代表常用的 CPython 实现.

不使用虚拟环境安装软件包

如前文所述, 在安装软件包时, 要避免和系统包管理管理的范畴发生冲突. 因此如果目标 Python 安装较为独立, 则可以考虑不使用虚拟环境, 直接安装在 Python 目录下.

比如, 在 Linux 上, 笔者倾向于使用较新的 Python 版本, 因此需要使用独立的 Python 安装. 如果读者同样使用非系统提供的 Python 安装, 则可以考虑这样安装软件包.

尽管如此, 仍建议仅对较为通用的软件包采用直接安装的方式. 如果某些软件包为若干项目的依赖, 且对特定版本有所要求, 则建议在虚拟环境中安装它们.

这里假设将最新的 Python 3.12.0 安装在了 $HOME/python3.12.0/ 目录下. 要使用这个 Python 安装, 可以将其下的 bin 目录 (临时) 添加在 PATH 最前边:

export PATH=$HOME/python3.12.0/bin:$PATH

之后再使用 python3 命令时, 便会调用到这个安装里的 Python.

此外, 也可以直接通过绝对路径 (比如 $HOME/python3.12.0/bin/python3) 调用该 Python.

在确定当前使用的具体 Python 安装 (以及 pip 安装) 的位置后, 直接使用 pip 安装软件包即可 (下以 jupyter 为例).

可以根据需要, 使用 python -m 调用 pip (推荐这种方式):

python -m pip install jupyter
# /path/to/python -m pip install jupyter

或直接调用 pip:

pip install jupyter
# /path/to/pip insall jupyter

需要注意, Linux 环境下可能需使用 python3pip3 代替 pythonpip.

Python 虚拟环境及其使用

Python 的 venv 模块可以创建轻量级的 “虚拟环境 (virtual environment)”, 每个虚拟环境中的软件包互不相干, 安装在各自的 site 目录下. 虚拟环境是基于某个现有的 Python 安装 — 称为 “基础 (base)” Python — 上建立的, 并且可以根据需要, 同样使虚拟环境与基础 Python 环境中的软件包隔开, 这样可以仅让显式在虚拟环境中安装的软件包生效.

虚拟环境:

  • 应当用于包含支持某个项目的特定 Python 解释器以及相关的软件库与二进制文件, 与其他虚拟环境中的软件以及系统中的 Python 解释器和软件库互不相干.
  • 应当被包含在单个目录下. 习惯上, 这个目录应位于项目目录下, 名为 venv.venv, 或与若干其它虚拟环境共同位于某一目录下, 如 ~/.virtualenvs.
  • 应当被排除在诸如 Git 等源代码控制系统的管理外.
  • 应当被视作可即用即弃的 — 虚拟环境应当易于删除并从头重新创建. 项目的代码不应置于虚拟环境中.
  • 不应被视作可移动或可拷贝的 — 应当在目标位置重新创建虚拟环境.

具体可以参见 PEP 405 以了解 Python 虚拟环境的更多背景.

从 Python 3.5 起, 便可以使用 Python 标准库中提供的 venv 模块创建虚拟环境. 比如:

python -m venv /path/to/new/virtual/environment

将会在指定目录下创建一个虚拟环境 (若目录不存在, 会逐级创建). 如果目录已存在, 将会复用这个目录.

除却生成一些配置外, 该过程会创建名为 bin 的子目录 (在 Windows 系统下为 Scripts), 在其中包含有到 Python 相关二进制文件的符号链接. 同时还会生成 lib/pythonX.Y/site-packages 的子目录 (在 Windows 系统下为 Lib\site-packages).

比如, 使用 python -m venv venv, 即可在当前目录下, 建立一个位于 venv 目录, 基于所使用 python 的虚拟环境.


当通过虚拟环境使用 Python 时, sys.prefix 以及 sys.exec_prefix 会指向这个虚拟环境, 而 sys.base_prefixsys.base_exec_prefix 则指向创建虚拟环境时所基于的 Python 安装.

虚拟环境目录下的 binary 目录 (对于 POSIX 平台为 bin, Windows 平台为 Scripts) 中包含有 activate 脚本, 可以用于 “激活 (activate)” 对应的虚拟环境.

总的来说, 该脚本会将这个 binary 目录添加到当前的 PATH 中, 这时再调用 python 便会调用该虚拟环境对应的 Python 解释器, 而无需使用绝对路径来指定.

在不同的平台下, 调用该脚本的方式也不尽相同.

  • 在 bash 中, 使用 source <venv>/bin/activate 应用 activate 脚本的内容.
  • 在 Windows 平台下, 若使用 CMD, 则使用 <venv>\Scripts\activate.bat 完成对应操作.
  • 在 Python 3.8 之后, 创建虚拟环境时会生成适用于 PowerShell 的 activate 脚本, 可用 <venv>/bin/Activate.ps1 (POSIX) 或 <venv>/Scripts/Activate.ps1 (Windows) 来激活虚拟环境.

需要注意, Windows 系统下可能需要设置当前用户的 Execution Policy 才能启用 Activate.ps1 脚本.

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

事实上, 可以通过指定路径虚拟环境中 Python 解释器的路径, 直接调用 Python, 而并不一定要激活虚拟环境. 更进一步来说, 虚拟环境中的所有脚本都可以直接使用; 这是因为这些脚本的 “shebang” 行所指向的, 即为虚拟环境中的 Python 解释器. 这意味着这些脚本的执行, 并不受 PATH 的影响. 在 Windows 上如果安装了 “Python Launcher for Windows (适用于 Windows 的 Python 启动器)”, 也能获得 “shebang” 支持.

由于这种设计需要脚本中的 “shebang” 行包含其所在虚拟环境中解释器的绝对路径, 因此一般来说虚拟环境不能被移动到其他地方使用. 若要在新的路径下使用, 应当重新创建虚拟环境 (比如, 创建新的虚拟环境后, 使用 pip 根据 requirements.txt 文件重新安装需要的软件包).

对于启用了的虚拟环境, 可以使用 deactivate 取消激活.


如上所述, 使用虚拟环境中的 Python (或 pip) 即可在虚拟环境中安装对应的包. 方式同上一节, 这里不再赘述.


Last modified on 2023-10-10