Skip to main content

日行一令:python -m venv

· 约7分钟
Proca

导语

多数情况下,在开发、运行Python项目时,我们需要使用诸如 pip 的包管理工具,在Python环境中查找、下载、安装、卸载各种Python包。通常,包都会被安装到Python安装目录的 site-packages 文件夹下。这样,在同一Python环境中的不同项目,都会使用 site-packages 下所安装的包。

但不同项目对于同一种包的版本需求可能不同,并且当我们使用 pip install <pkgname> 时,通常不会仅仅安装一种包:

pip install Scrapy
...
Installing collected packages: PyDispatcher, pyasn1, incremental, constantly, zope.interface, w3lib, typing-extensions, six, queuelib, pycparser, pyasn1-modules, lxml, jmespath, itemadapter, hyperlink, filelock, cssselect, attrs, requests-file, protego, parsel, cffi, Automat, Twisted, tldextract, itemloaders, cryptography, service-identity, pyOpenSSL, Scrapy
...

可见,如果我们都只在单一Python环境中运行我们所有的项目,必定会带来包的版本混乱。最简单的方法是把不同的项目放在不同的Python环境中运行。

而命令 python -m venv 正是实现这一步的不二法宝。

在了解虚拟环境之前...

我们知道,在同一个操作系统中,多个版本的Python可以同时共存,多个相同版本的Python副本也可以互不干扰,每个Python安装目录都可被视为一个独立的Python环境。下面这张梗图很形象地说明了这一特点。

meme

那么,这是否意味着对于每个不同的项目,我们都要手动地拷贝一份新的Python,再到这份Python副本中运行这一项目呢?直觉告诉我们这太麻烦了:不仅得手动操作,还得等待标准库的拷贝。在时间以及存储空间方面看来,这都不是好方案。

因此,早在Python2时代,就有了 virtualenv 这样的工具帮助我们创建一个虚拟环境,从而便利地解决了包的版本混乱问题。在经过版本的迭代后,从Python3.3开始,虚拟环境 venv (操作仍与 virtualenv 类似)便被集成进Python的标准库中。

以下,我们通过实践来说明虚拟环境 venv 的用法。

尝试使用Python虚拟环境

某一天,你的朋友给你发了一份简单的Python代码,让你试着帮他测试一下运行情况。

// app.py
import time
import cv2 as cv
import numpy as np
import math

def getBinarizationPicture(image, color="RED"):
imageChannels = cv.split(image)
if color == "RED":
image = cv.subtract(imageChannels[2], imageChannels[0])
elif color == "BLUE":
image = cv.subtract(imageChannels[0], imageChannels[2])
image = cv.threshold(image, 120, 255, cv.THRESH_BINARY)
element = cv.getStructuringElement(cv.MORPH_RECT, [6,6])
image = cv.dilate(image[1], element)

return image


def getAllContours(image):

...

这是一个基于YOLOv7目标检测算法的简单程序。显然,该程序的运行需要OpenCV库。为了保证我们机器中Python环境的“简洁”,对于这样的任务,我们倾向于在虚拟环境中运行。

  1. 在终端下执行以下命令,创建一个虚拟环境。
python -m venv yolov7env

这样,当前目录下便会出现一个名为 yolov7env 的新文件夹,我们把这个目录称为虚拟环境 yolov7env 。在这个虚拟环境中,包含如下内容:

a. 文件夹 /bin ,包含了 python 的快捷方式、 pip 包管理工具,以及我们激活虚拟环境所需要 activate 文件。

b. 文件夹 /lib,其中的 /site-packages 将存放我们稍后安装的第三方库。

  1. 接着,进入 /bin
cd bin
  1. 执行如下命令,激活虚拟环境。
source activate

激活成功后,终端的用户名前会出现虚拟环境名称:

(yolov7env) proca@xxx bin %

我们知道,在Python的安装过程中,会修改系统环境变量:包括指定Python可执行文件的位置、指定Python标准库的位置、指定第三方库的位置等。而“激活”虚拟环境所做的,正是修改原始系统环境变量:重新指定第三方库的位置,以实现不同环境下包的隔离。

例如,激活虚拟环境后,运行Python,并执行如下代码:

import sys
from pprint import pprint
pprint(sys.path)

输出包含如下内容:

...

'/Users/proca/Documents/yolov7env/lib/python3.10/site-packages'

可以发现,现在第三方库的位置发生了改变。

注意:虚拟环境中通过引用来使用Python标准库

  1. 激活成功后,便可以常规地使用Python。

例如,使用 pip 安装opencv。

pip install opencv-python

安装成功:

...

Successfully installed numpy-1.23.4 opencv-python-4.6.0.66

不忘初心,运行朋友发过来的Python代码:

python app.py

大功告成!: app

  1. 工作完成后,执行如下命令退出激活环境:
deactivate
  1. 最后,我们可以把该虚拟环境删除,就像什么都没发生过一样
rm -rf yolov7env

拓展

上面的那份Python代码只需要我们在环境中执行 pip install opencv-python 便可顺利运行。但如果我们的项目依赖于更多第三方库,当我们想让别人调试、运行我们的程序时,该怎么办呢? pip 作为一个包管理工具,提供了针对这一情况的便利方法:

在当前python环境执行以下命令:

pip freeze > requirements.txt

在把 requirements.txt 发送给别人后,Ta只要执行如下命令:

pip install -r requirements.txt

便可得到对应版本的第三方库。

支持一下

暂无评论,来留下友好的评论吧