文章目录
- 一、虚拟环境介绍
- 1.1 为什么需要虚拟环境
- 1.2 什么是虚拟环境
- 1.2.1 venv常用命令
- 1.2.2 虚拟环境的文件夹结构
- 1.2.3 虚拟环境的隔离性
- 二、虚拟环境是如何工作的
- 2.1 复制结构和文件
- 2.2 调整前缀查找过程
- 2.2.1 系统前缀查找过程
- 2.2.2 虚拟环境前缀查找过程
- 2.3 链接回标准库
- 2.4 修改 `PYTHONPATH` 环境变量
- 2.5 虚拟环境激活时更改 shell `PATH` 变量
- 2.6 使用绝对路径运行虚拟环境
- 三、自定义虚拟环境
- 四、如何管理虚拟环境
- 4.1 虚拟环境的创建方式
- 4.2 虚拟环境是可丢弃的
- 4.3 虚拟环境的可重现性
- 4.4 避免在生产环境中使用虚拟环境
- 五、其它虚拟环境工具
- 5.1 Virtualenv
- 5.2 Conda
- 5.3 不同虚拟环境管理工具的对比
- 5.4 使用第三方工具
- 原文:《Python Virtual Environments: A Primer》、课程视频、课程测试
- venv官方文档、virtualenv文档、
- Miniconda官网、Anaconda官网、conda文档
本教程将指导您学习使用 Python 的 venv 模块创建和管理虚拟环境,该模块是Python标准库的一部分,且一直是官方推荐的创建虚拟环境的方法。虚拟环境允许开发者为不同的项目创建隔离的Python运行环境,这样可以避免不同项目之间的依赖冲突,并且可以灵活地管理项目所需的Python版本和库。
一、虚拟环境介绍
1.1 为什么需要虚拟环境
使用Python虚拟环境有以下几个关键原因:
-
避免系统污染
Linux和macOS等操作系统通常预装有Python,并用于系统内部任务。如果在系统的全局Python环境中安装外部软件包,这些软件包可能与系统相关的软件包混合,导致意外的副作用,影响操作系统的正常行为。此外,如果操作系统进行更新,可能会覆盖和丢失已安装的软件包,导致工作中断和问题。 -
解决依赖冲突
不同的项目可能需要使用不同版本的外部库,而在全局环境中只能安装一个版本,所以会导致版本冲突问题。使用虚拟环境可以为每个项目创建独立的环境,从而安装所需的不同版本库,避免版本覆盖和冲突。 -
最小化可重现性问题
将所有软件包集中在全局环境中会导致很难区分哪些依赖属于哪个项目,这对项目的可维护性和共享性是不利的。
假设你同时在进行一个网络爬虫项目和一个Flask应用,并将所需的所有软件包都安装在全局环境中,这样会难以明确区分不同项目的依赖。如果使用虚拟环境,每个项目的依赖都会在其独立环境中,这样可以更轻松地读取项目需求并与他人共享,减少错误和混淆。 -
避免安装权限限制
在一些公司环境中,用户可能没有管理员权限,无法在主机Python的site-packages
目录中安装软件包。虚拟环境在用户权限范围内创建新的安装位置,无需管理员权限即可安装和使用外部软件包。
1.2 什么是虚拟环境
1.2.1 venv常用命令
venv常用命令 | 说明 |
---|---|
python -m venv <env_name> | 在当前目录下创建虚拟环境 |
<env_name>\Scripts\activate | 激活虚拟环境 |
deactivate | 退出虚拟环境 |
pip install <package> | 在激活的虚拟环境中安装软件包 |
pip list | 列出虚拟环境中已安装的软件包 |
pip uninstall <package> | 卸载虚拟环境中的软件包 |
pip freeze > requirements.txt | 将当前虚拟环境中的包导出到requirements.txt 文件 |
pip install -r requirements.txt | 从requirements.txt 文件安装包到虚拟环境 |
python -m pip install --upgrade pip | 升级虚拟环境中的pip 版本 |
以上是venv常用命令,这些命令帮助用户在Windows平台上创建、管理和使用Python虚拟环境。那到底什么是Python虚拟环境?
Python虚拟环境本质上是一个文件夹结构,复制或软链接了Python可执行文件。它为用户提供了运行一个轻量且隔离的Python环境所需的一切,使用户能够在其中运行Python程序,并安装和管理与该环境相关的库和包,而不会影响到全局的Python环境或其他项目的环境。
虚拟环境只是一个文件夹结构,这意味着您可以随时删除和重新创建。
1.2.2 虚拟环境的文件夹结构
创建虚拟环境时,venv
模块会生成以下的基本文件和文件夹结构:
PS> tree venv\ /F
venv\
│
├── Include\
│
├── Lib\
│ │
│ └── site-packages\
│ │
│ ├── pip\
│ │
│ └── pip-24.2.dist-info\
│
│
├── Scripts\
│ ├── Activate.ps1
│ ├── activate
│ ├── activate.bat
│ ├── deactivate.bat
│ ├── pip.exe
│ ├── pip3.12.exe
│ ├── pip3.exe
│ ├── python.exe
│ └── pythonw.exe
│
└── pyvenv.cfg
- Include\:初始为空的文件夹,供安装依赖C扩展的包使用,以存放C头文件。
- Lib\:包含
site-packages\\
文件夹,这是虚拟环境创建的主要原因之一。site-packages\\
目录用于存放在虚拟环境中安装的外部包。Python 3.12起,虚拟环境默认只包含pip
。 - Scripts\:包含虚拟环境的可执行文件,如Python解释器(
python.exe
)、pip
可执行文件(pip.exe
)以及用于激活环境的脚本(如activate
、activate.bat
)。 - pyvenv.cfg:关键配置文件,包含用于设置
sys
模块变量的键值对,决定当前Python会话使用哪个解释器和site-packages
目录。 - {name}-{version}.dist-info/:当你使用pip安装Python包时,默认会创建此目录,其中包含了关于已安装包的分发信息。
仔细查看上面的文件夹结构,可以发现虚拟环境由三个关键部分组成:
- Python二进制文件的副本或符号链接:用于运行与虚拟环境关联的Python解释器。
- pyvenv.cfg文件:存储Python会话的一些配置信息。
- site-packages目录:存放在该虚拟环境中安装的外部库。
- 在
Windows
和Linux
系统中,虚拟环境里的Python可执行文件可能是原始Python可执行文件的符号链接(symlink)。- 在
macOS
系统中,虚拟环境里的Python可执行文件总是原始文件的复制品。- 即使
site-packages
目录为空,虚拟环境仍然是有效的。默认情况下,venv
会安装pip
,因为pip
是安装Python软件包的推荐工具。- 如果你使用的Python版本早于
3.12
,那么使用venv
新建的虚拟环境中,会预先安装一些包,比如setuptools
、pkg_resources
等,而不只有pip
包。
创建虚拟环境后,可以使用pip list
命令来确认pip
是否已被安装:
(venv) PS> python -m pip list
Package Version
---------- -------
pip 24.2
1.2.3 虚拟环境的隔离性
虚拟环境的目的是在不影响全局Python环境的情况下安装外部包。为实现这一点,venv
会复制或链接标准Python安装中的文件结构。不同操作系统的行为有所不同,Windows和Linux可能会创建符号链接,而macOS则总是复制。
-
pyvenv.cfg 文件
该配置文件包含关键的设置,用于定义虚拟环境的行为,例如Python解释器路径和是否包含系统级site-packages
的访问。示例配置内容如下:home = C:\Users\Name\AppData\Local\Programs\Python\Python312 include-system-site-packages = false version = 3.12.5 executable = C:\Users\Name\AppData\Local\Programs\Python\Python312\python312.exe command = C:\Users\Name\AppData\Local\Programs\Python\Python312\python312.exe -m venv C:\Users\Name\path\to\project\venv
-
标准库访问
虽然新建的虚拟环境文件夹结构中不包含Python标准库模块(site-packages中只有pip模块),但激活虚拟环境后,你仍然可以导入和使用标准库模块。这是因为虚拟环境实现了到系统基本Python标准库的链接。这种行为避免了复制标准库,提高了虚拟环境创建的速度和效率。# 新创建的虚拟环境没有安装标准库,但仍能成功导入 >>> import urllib >>> from pprint import pp >>> pp(dir(urllib)) ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
-
共享
site-packages
的选项
你可以在创建虚拟环境时使用--system-site-packages
选项,以访问系统Python安装中的site-packages
目录:py -m venv venv\ --system-site-packages
此设置会将pyvenv.cfg
中的include-system-site-packages
值设为true
,允许虚拟环境使用系统Python的外部包。不过,这种访问是单向的,只是为虚拟环境提供了访问源Python的site-packages文件夹的权限,您安装到虚拟环境中的任何新包都不会与那里的包混合在一起。
总结:虚拟环境实际上是包含特定设置文件的文件夹结构。它可以选择性地预装pip
,复用源Python的标准库,同时保持安装的隔离性,从而实现更轻量和高效的环境管理。但是,您可能仍然想知道所有这些是如何工作的,接下来您将深入研究。
二、虚拟环境是如何工作的
2.1 复制结构和文件
- 结构相似:当你使用venv创建虚拟环境时,Python会重新创建标准Python安装的文件和文件夹结构。虚拟环境的文件夹结构与系统级Python安装相似,以确保Python在隔离环境中正常运行而无需额外更改。
- Python可执行文件:在Windows上,虚拟环境中的
python.exe
位于Scripts\
文件夹,而系统Python中的python.exe
通常位于更高一级的目录。这一结构调整简化了激活虚拟环境时路径(PATH)变量的设置。
2.2 调整前缀查找过程
2.2.1 系统前缀查找过程
Python解释器的前缀查找过程旨在定位Python解释器运行所需的核心组件,如标准库、头文件和site-packages目录。这个过程主要依赖于sys模块中的一些关键变量。
-
前缀变量
sys.prefix
:指向系统Python安装的根目录,包含Python解释器和相关文件,如标准库和site-packages目录。sys.exec_prefix
:与sys.prefix
类似,但用于定位平台相关的库和资源(例如,编译的二进制模块), 一般情况下与sys.prefix
相同。sys.base_prefix
:- 在没有虚拟环境时,
sys.base_prefix
与sys.prefix
相同,表示系统级Python安装的根目录。 - 当处于虚拟环境时,
sys.base_prefix
指向基础Python安装,以便访问标准库。而sys.prefix
指向虚拟环境目录,使得模块和包的查找、安装与系统环境隔离。
- 在没有虚拟环境时,
-
模块查找过程
sys.path
:Python解释器使用该列表来搜索模块。sys.path
中包含的路径会根据sys.prefix
和sys.exec_prefix
生成,通常包括以下内容:- Python安装目录下的
Lib
文件夹,用于访问标准库模块。 Lib\site-packages
文件夹,用于访问安装的第三方包。- 其他环境变量和用户指定的路径。
- Python安装目录下的
>>> import sys
>>> sys.prefix
'C:\\Python39' # 系统Python安装目录
>>> sys.base_prefix
'C:\\Python39' # 与sys.prefix一致
>>> sys.path
['', 'C:\\Python39\\Lib', 'C:\\Python39\\Lib\\site-packages', ...]
2.2.2 虚拟环境前缀查找过程
在使用 venv 创建的虚拟环境中,Python 解释器通过查找 pyvenv.cfg
文件来决定虚拟环境是否存在。该文件中包含home
键,解释器会使用它设置两个变量:
-
sys.base_prefix
:保存用于创建虚拟环境的Python可执行文件的路径,即home 键的值。 -
sys.prefix
:指向包含pyvenv.cfg
的目录,即虚拟环境目录。 -
在虚拟环境中,
sys.base_prefix
和sys.prefix
指向不同位置:>>> import sys >>> sys.base_prefix 'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312' >>> sys.prefix 'C:\\Users\\Name\\path\\to\\venv'
-
在非虚拟环境中, 两个变量都指向相同路径。
>>> import sys >>> sys.base_prefix 'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312' >>> sys.prefix 'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312'
这种差异让Python解释器能够在虚拟环境中使用基础Python安装的标准库模块,同时将外部包安装在虚拟环境的独立site-packages
目录中。
2.3 链接回标准库
Python虚拟环境旨在以一种轻量级的方式为您提供一个隔离的Python环境,您可以快速创建,然后在不再需要时删除。为了实现这一点,venv只复制最低限度需要的文件,即Python二进制文件的一个副本或符号链接,以及一个pyvenv.cfg文件和一个site-packages目录。
虚拟环境中的Python可执行文件可以访问作为环境基础的Python安装的标准库模块。Python通过在pyvenv.cfg的home设置中指向基本Python可执行文件的文件路径来实现这一点。
在 Python 会话中, sys.path
决定了 Python 可以从哪些位置导入模块。如果激活虚拟环境并进入 Python 解释器,你会发现基础 Python 安装的标准库路径包含在 sys.path
中。因此,即使在虚拟环境中工作,Python 仍然可以导入标准库模块。
>>> import sys
>>> sys.path
['',
'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312\\python312.zip',
'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312\\DLLs',
'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312\\lib', # 系统python标准库位置
'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312',
'C:\\Users\\Name\\path\\to\\venv',
'C:\\Users\\Name\\path\\to\\venv\\lib\\site-packages']
2.4 修改 PYTHONPATH
环境变量
默认情况下,sys.path
包含系统 Python 的安装路径,包括 site-packages
目录,用于存放通过 pip
安装的外部模块。当激活虚拟环境后,sys.path
更新为使用虚拟环境中的 site-packages
路径,屏蔽系统 Python 的 site-packages
,实现外部包的隔离。
# 虚拟环境未启动时,site-packages在系统python目录下
>>> import sys
>>> sys.path
['',
'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312\\python312.zip',
'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312\\DLLs',
'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312\\lib',
'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312',
'C:\\Users\\Name\\AppData\\Roaming\\Python\\Python312\\site-packages',
'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312\\lib\\site-packages']
# 启动虚拟环境后,site-packages在虚拟环境目录下
>>> import sys
>>> sys.path
['',
'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312\\python312.zip',
'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312\\DLLs',
'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312\\lib',
'C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312',
'C:\\Users\\Name\\path\\to\\venv',
'C:\\Users\\Name\\path\\to\\venv\\lib\\site-packages']
2.5 虚拟环境激活时更改 shell PATH
变量
要激活虚拟环境,您需要执行激活脚本。不同操作系统和 shell 会选择不同的脚本,如 activate
、activate.bat
、Activate.ps1
。
PS> venv\Scripts\activate
(venv) PS>
PATH 是一个包含多个目录路径的环境变量,当你在命令行中输入 python 或 pip 等命令时,系统会按从左到右的顺序搜索这些目录,找到第一个匹配的可执行文件就立即执行。当你激活环境时,会发生两个关键性的操作:
-
VIRTUAL_ENV
变量会被设置为虚拟环境的根目录路径,并且会将虚拟环境中 python 和 pip 的路径添加到 PATH 的最前面,使得 shell 调用时优先使用虚拟环境中的python
和pip
。 -
命令提示符会改变为虚拟环境的名称(如
(venv)
),方便确认当前虚拟环境是否被激活。
如果使用 deactivate
命令取消激活( Windows 上运行deactivate.bat
)可将 PATH
和命令提示符恢复到激活前的状态。激活和取消激活的脚本帮助实现路径和提示符的临时变化,不会永久修改系统配置。这些变化虽小但提高了使用虚拟环境的便利性。
2.6 使用绝对路径运行虚拟环境
虽然推荐激活虚拟环境以方便使用,但实际上你可以不激活它,只需提供虚拟环境中 Python 可执行文件的绝对路径,这使得你能够在同一脚本中同时使用系统 Python 和虚拟环境中的 Python。例如,在 Windows 上可以使用:
PS> C:\Users\Name\path\to\venv\Scripts\python.exe
您可以通过启动解释器并运行
import sys; sys.executable
来确认您正在使用哪个Python可执行文件。这些命令将返回当前Python解释器的绝对路径,看看是不是与先激活虚拟环境再运行python时启动的解释器相同。
绝对路径对于在远程服务器或 Docker 容器中运行的脚本很有帮助,特别是在涉及自动化任务(如 CRON 作业)时,绝对路径提供了更加稳定和可控的方式来确保脚本使用虚拟环境中的正确解释器和依赖。
假设你有一个定时任务,想要使用虚拟环境中的 Python 解释器运行一个脚本(例如,每小时检查网站连接)。在 Linux 系统上,使用 CRON 作业时,你可以在 crontab 文件中写入以下内容:
0 * * * * /home/name/Documents/connectivity-checker/venv/bin/python -m rpchecker -u google.com twitter.com -a
这条命令会在每小时执行一次 rpchecker 脚本,使用 /home/name/Documents/connectivity-checker/venv/bin/python 中的 Python 解释器,并且只使用虚拟环境中安装的依赖(例如 aiohttp)。这种方式避免了激活虚拟环境的麻烦(在脚本中嵌入虚拟环境的激活是一项繁琐的工作,出错的频率很高),确保任务的隔离性和可重复性。
Docker 容器通常是轻量级的、独立的环境,可能不包含系统级 Python 或一些依赖库。因此,在 Docker 容器中使用绝对路径来调用虚拟环境中的 Python 解释器可以确保容器内的 Python 环境和依赖是正确配置的。这样可以避免与 Docker 容器外部环境的 Python 版本或库发生冲突。
三、自定义虚拟环境
以上内容介绍了如何自定义虚拟环境(virtual environment),使用 venv
模块创建虚拟环境时,可以通过不同的选项来定制环境的行为和外观。以下是各项自定义功能的总结:
-
更改命令提示符:
可以通过--prompt
参数自定义激活虚拟环境时的命令提示符,例如将其改为项目名或其他描述性字符串,而不必更改虚拟环境文件夹的名称。例如下面代码中,虚拟文件夹名还是venv
,但激活时虚拟环境名为dev-env
。PS> py -m venv venv\ --prompt dev-env PS> venv\Scripts\activate (dev-env) PS>
-
覆盖已有环境:使用
--clear
参数可以在创建新虚拟环境时自动删除已有的同名虚拟环境,避免手动删除的麻烦。PS> py -m venv venv\ --clear
-
一次创建多个虚拟环境:通过传递多个路径,可以一次创建多个虚拟环境,减少重复操作。
PS> py -m venv venv\ C:\Users\Name\Documents\virtualenvs\venv-copy\
在上面的例子中,第一个参数
venv\
表示一个相对路径,表示在当前目录创建虚拟环境。相反,第二个参数使用一个绝对路径指向一个新的文件夹位置。多个路径中间用空格隔开就行。
-
更新pip:默认情况下,虚拟环境创建时可能会包含过时的
pip
版本。可以使用--upgrade-deps
参数自动更新pip
,避免手动更新。 -
避免安装
pip
:如果不需要pip
,可以使用--without-pip
参数创建一个没有pip
的虚拟环境,减少环境的大小。 -
访问系统站点包:通过
--system-site-packages
参数,可以让虚拟环境访问全局 Python 安装的site-packages
目录(可运行sys.path
进行检查),避免每次都重新安装大型库(如 PyTorch 或 TensorFlow)。 -
复制或链接可执行文件:可以使用
--symlinks
或--copies
参数来决定是否创建符号链接或复制 Python 可执行文件。不同操作系统的默认行为可能有所不同。 -
升级 Python 版本:
- 当你使用
venv
创建完虚拟环境时,如果选择了复制(而非符号链接)Python 可执行文件,后来又更新了系统中的 Python 版本,你可能会遇到标准库版本不匹配的问题。 - 使用
--upgrade
参数,可以将虚拟环境中的 Python 和 pip 可执行文件更新为系统中的新版本,同时保持虚拟环境中的site-packages
目录(即已安装的第三方库)不变
PS> py -m venv venv\ --upgrade
- 当你使用
以上这些自定义选项让 venv
在创建虚拟环境时更具灵活性,能够根据不同的需求进行优化和调整。
四、如何管理虚拟环境
4.1 虚拟环境的创建方式
有两种主要的虚拟环境位置选择:
特点 | 1. 项目文件夹内创建虚拟环境 | 2. 单一文件夹存放所有虚拟环境 |
---|---|---|
结构 | 虚拟环境与项目代码一起放在同一文件夹中,如 project_name/venv/ | 所有虚拟环境存放在一个文件夹中,例如家目录下的 ~/.venvs/ |
激活方式 | 相对路径(例如 ./venv/bin/activate ) | 绝对路径(例如 ~/.venvs/project_name/bin/activate ) |
管理 | 每个项目独立管理其虚拟环境,便于区分和跟踪 | 虚拟环境集中管理,可以在一个地方查看和清理所有环境 |
磁盘空间占用 | 每个项目都有独立的虚拟环境,多个项目会占用更多的磁盘空间 | 虚拟环境集中存放,可以减少磁盘空间的重复使用 |
适用场景 | 适合需要对每个项目独立管理和隔离环境的开发 | 适合管理多个虚拟环境,尤其是需要共享 Python 环境的情况 |
你也可以选择将虚拟环境创建在任意位置,甚至两种方式结合使用,根据个人工作流的不同来选择最合适的结构。另外一些 IDE(如 VS Code 和 PyCharm)提供了自动创建虚拟环境的功能,你可以直接让 IDE 来处理虚拟环境的创建和管理。
4.2 虚拟环境是可丢弃的
虚拟环境是临时的,可以随时删除并重新创建而不丢失代码相关的信息。以下是几个关键点:
-
避免手动添加代码到虚拟环境:
不应在虚拟环境中手动添加任何代码,比如项目代码,所有依赖包应该由包管理工具(如 pip 或 conda)来管理。 -
不要将虚拟环境提交到版本控制:
- 虚拟环境不应推送到版本控制系统(如 Git)中,也不应随项目一起发布,因为虚拟环境安装很多包,体积太大,而且虚拟环境可能包含一些敏感数据(如密钥、凭证等),不应泄露。
- 只需要将
requirements.txt
或Pipfile
这类记录依赖信息的文件提交到版本控制中,而将虚拟环境文件夹添加到.gitignore
文件中,这样可以避免虚拟环境被提交到 Git 仓库中。
4.3 虚拟环境的可重现性
生成 requirements.txt 文件:尽管虚拟环境是可丢弃的,但为了在其他机器上重现该环境,你需要保存虚拟环境中安装的依赖。最常见的方法是使用 requirements.txt
文件。你可以在虚拟环境激活后,通过 pip freeze > requirements.txt
命令生成当前环境中的所有外部依赖,并将其保存到 requirements.txt
文件中。
如果没有激活虚拟环境,pip freeze 会列出全局环境中的依赖,可能会包含系统级别的包和不相关的库。
重新创建虚拟环境: 通过 python -m venv
命令创建一个新的虚拟环境,然后使用 pip install -r requirements.txt
安装所有依赖,这样就能保证新的虚拟环境与原环境一致。
requirements.txt的局限性: 如果你将 requirements.txt
提交到版本控制中,其他开发者可以使用它来重建相同的虚拟环境,这是一种常见做法,但它并不完美。主要存在以下问题:
- Python 版本问题:
requirements.txt
不包含创建虚拟环境时使用的 Python 版本信息。 - 子依赖问题:
requirements.txt
可能不包含依赖项的子依赖版本信息,可能导致在安装时获取不同版本的包。
使用第三方工具保证可重复构建:基于requirements.txt
的局限性,许多第三方依赖管理工具试图构建更准确的虚拟环境依赖。
- pip-tools:通过
pip-tools
管理依赖项,可以生成更精确的锁定文件。 - Pipenv:提供 Pipfile.lock 文件,能够保证更严格的版本控制。
- Poetry:使用 poetry.lock 文件来确保项目环境的一致性。
4.4 避免在生产环境中使用虚拟环境
不要将虚拟环境文件夹推送到远程仓库(例如 GitHub )或部署服务器(例如 Heroku、Google App Engine 等),在持续集成(CI)或持续交付(CD)的流水线中,也不应该包含虚拟环境文件夹。而应该通过锁定依赖的方式,确保环境的一致性。对于大多数托管平台,它们会自动提供隔离环境,而你只需要通过 requirements.txt
指定需要的库即可。
除非自己管理服务器,并且运行多个项目,才需要考虑在服务器上创建虚拟环境,但也应该根据 requirements.txt重新创建,而不是复制虚拟环境文件夹。
五、其它虚拟环境工具
5.1 Virtualenv
virtualenv 是一个在 Python 中创建隔离的虚拟环境的工具。
命令 | 功能说明 |
---|---|
virtualenv <env_name> | 创建一个名为 <env_name> 的虚拟环境 |
source <env_name>/bin/activate | 激活虚拟环境 (Linux/Mac) |
<env_name>\Scripts\activate | 激活虚拟环境 (Windows) |
deactivate | 退出当前虚拟环境 |
virtualenv --version | 查看 virtualenv 的版本 |
virtualenv -p python3 <env_name> | 使用特定 Python 版本创建虚拟环境 (如 python3 ) |
virtualenv -p /usr/bin/python3.8 [env_name] | 使用指定路径的 Python 解释器创建虚拟环境(例如,使用 Python 3.8)。 |
virtualenv --system-site-packages <env_name> | 使虚拟环境可以访问系统里的python包 |
rm -rf <env_name> | 删除虚拟环境 |
pip freeze > requirements.txt | 导出当前虚拟环境的依赖包列表至 requirements.txt 文件 |
pip install -r requirements.txt | 根据 requirements.txt 安装依赖包 |
创建并激活虚拟环境venv
之后,直接进行pip安装我们需要的库:
# 创建虚拟环境
virtualenv venv
# 可在venv\Scripts文件夹的地址栏打开cmd,即切换到Scripts目录,然后输入activate命令激活虚拟环境
venv\Scripts\activate
pip install opencv-python==3.4.1.15 opencv-contrib-python==3.4.1.15 jupyter matplotlib -i https://pypi.douban.com/simple
5.2 Conda
Miniconda、Anaconda、conda文档
venv和 Virtualenv只创建和管理 Python 虚拟环境,不能管理非 Python 包。如果需要同时管理 Python 包和非 Python 依赖项(如 C 库、工具包等),通常推荐使用 Conda。
conda 是一个跨平台的虚拟环境管理器,不仅支持 Python,还支持其他编程语言,也可以管理系统依赖项,目前有两个版本——Miniconda和Anaconda。前者只有几百M,是最小化版本,只包括Conda和Python,用户可以自定义需要安装的其它包。而后者有5、6G,预装了许多包,适用于各种数据科学任务。以下是一些常用的conda命令:
conda包管理命令 | 描述 |
---|---|
conda create --name myenv python=3.8 | 创建名为myenv的虚拟环境,指定python版本为3.8 |
conda activate myenv source activate myenv | 激活虚拟环境(windows) 激活虚拟环境(macOS和Linux) |
conda install package_name | 在激活的虚拟环境中安装Python包 |
conda list | 列出当前虚拟环境中已安装的包 |
conda deactivate | 停用当前虚拟环境 |
conda env export > environment.yml | 导出当前虚拟环境的配置到一个YAML文件 |
conda env create -f environment.yml | 根据YAML文件创建虚拟环境 |
conda remove --name myenv --all | 删除指定名称的虚拟环境及其所有包 |
conda search package_name | 搜索可用于安装的包 |
conda update --all | 升级当前虚拟环境中的所有包 |
conda虚拟环境管理命令 | 描述 |
---|---|
conda update conda | 升级conda本身 |
conda config --show | 显示conda的配置信息 |
conda env list | 列出所有已创建的虚拟环境 |
conda info --env | 显示当前虚拟环境的详细信息 |
conda config --set auto_activate_base false | 禁用默认激活基础环境(默认情况下会自动激活基础环境) |
conda config --set auto_activate your_env_name | 设置your_env_name为默认的激活环境 |
默认情况下,conda自动激活base环境为当前使用环境。如果要更改某个环境为默认激活环境,你需要进行一下操作:
conda config --set auto_activate_base false # 禁用默认激活基础环境
conda config --set auto_activate your_env_name # 设置your_env_name为默认的激活环境
如果要恢复默认激活base环境,需要运行:
conda config --set auto_activate_base true # 恢复默认激活base环境
5.3 不同虚拟环境管理工具的对比
特性 | Virtualenv | venv | conda |
---|---|---|---|
来源 | 第三方库,需要通过 pip 安装 | Python 标准库,自 Python 3.3 起自带 | 独立于 Python 的包和环境管理工具 |
Python 版本支持 | 支持创建不同版本的 Python 虚拟环境 | 只能使用当前 Python 版本 | 支持多版本的 Python 安装与切换 |
包管理 | 使用 pip 进行包管理 | 使用 pip 进行包管理 | 使用 conda 自带的包管理器(也支持 pip ) |
安装方式 | 需要通过 pip install virtualenv | Python 自带,使用 python -m venv | 需安装 Anaconda 或 Miniconda |
使用场景 | 开发复杂项目时需要额外功能或支持多 Python 版本时使用 | 简单项目或仅需基本的虚拟环境隔离时使用 | 数据科学、机器学习、需要同时管理 Python 和非 Python 包时使用 |
功能丰富度 | 支持更多配置选项,如与不同版本的兼容性(支持python2) | virtualenv 简化版,满足大多基础功能 | 功能最丰富,支持虚拟环境、依赖和包的整体管理 |
系统依赖管理 | 不支持系统级依赖管理 | 不支持系统级依赖管理 | 支持系统级依赖和 C 库等非 Python 依赖 |
更新周期 | 独立于 Python 的更新,更新较频繁 | 随 Python 更新,更新频率较慢 | 独立更新,受 conda 社区支持,更新较快 |
环境大小 | 虚拟环境体积相对较小 | 虚拟环境体积较小 | 环境体积较大,但管理更方便 |
总结:
- Virtualenv :允许用户创建使用不同于当前系统的 Python 版本的虚拟环境,适合需要跨版本支持和更多定制功能的项目。
- venv :使用当前系统默认的Python 版本创建虚拟环境,适合日常开发和轻量级虚拟环境创建。
- conda :适合需要管理 Python 和其他非 Python 依赖的大型数据科学和机器学习项目。
virtualenv
本身并不会自动下载缺失的 Python 版本。如果你想使用一个没有安装的版本,需要首先手动安装该版本。假如你的系统中安装了多个 Python 版本,你可以通过 virtualenv 指定使用某个特定版本来创建虚拟环境,而不是使用系统默认的 Python 版本。
对于自动安装不同 Python 版本的功能,可以考虑使用pyenv
或conda
5.4 使用第三方工具
Python 社区开发了许多虚拟环境管理的第三方工具,以下是一些流行工具的概述:
-
virtualenvwrapper:这是一个
virtualenv
的扩展,简化了虚拟环境的创建、删除和管理。它将所有虚拟环境集中管理,并提供用户友好的命令行命令,帮助你在不同的虚拟环境间切换。virtualenvwrapper-win 是它的 Windows 版本。 -
Poetry:一个 Python 依赖管理和打包工具,类似于
requirements.txt
,但提供了更确定性的依赖管理。Poetry 会在自动生成的虚拟环境中安装依赖,并帮助你管理虚拟环境。用法详见《Dependency Management With Python Poetry》。 -
Pipenv:类似
Poetry
,旨在改善 Python 包管理,提供确定性的构建方式。它使用virtualenv
创建和管理项目的虚拟环境, 是一个相对较慢的高层次工具。 -
uv:这是一个多功能命令行工具,旨在统一管理 Python 包、依赖和虚拟环境。它通过整合多个工具(如 pip、virtualenv 和 pyenv),提供一个统一的界面来执行任务,比如安装包、管理虚拟环境和处理 Python 版本等。
-
Hatch: 这是一个现代的 Python 项目管理工具,简化了环境创建、依赖管理和打包。它允许你定义项目特定的配置,自动化创建隔离环境,支持多环境测试和版本管理等高级功能。
-
pipx:这是一个安装 Python 应用程序的工具,适用于那些作为独立可执行文件运行的工具。通过
pipx
,你可以为每个工具创建虚拟环境,并使其全局可用,常用于代码质量工具(如 black、isort、flake8、Pylint、mypy)以及替代 Python 解释器(如 bpython、ptpython、IPython)的安装。用法详见《Install and Execute Python Applications Using pipx》 -
pipx-in-pipx:用来安装
pipx
的包装器,允许你通过pipx
安装和管理pipx
本身。 -
pyenv:
pyenv
主要用于管理 Python 版本,虽然它不直接与虚拟环境相关,但常常与虚拟环境一起使用。它允许你在多个 Python 版本之间切换,方便你使用不同版本的 Python 开发项目。用法详见《Managing Multiple Python Versions With pyenv》 -
pyenv-virtualenv:
pyenv
的一个插件,它结合了pyenv
和virtualenv
,可以为pyenv
管理的 Python 版本创建虚拟环境。它还支持与virtualenvwrapper
一起使用,提供更多管理功能。
这些工具虽然可以帮助你管理虚拟环境,但它们并不是专门为了虚拟环境而设计的。它们的目标是提供更多功能和便利,而虚拟环境仅是其中的一部分。你可以根据需要选择合适的工具来管理你的 Python 版本和虚拟环境。