Python虚拟环境指南:告别依赖地狱

一、背景

在SAAS(软件即服务)平台中,用户使用自行定制的Python脚本已经成为司空见惯的做法,然而,由于不同用户对Python三方库的需求各不相同,而底层服务器一般只安装了一个Python版本。举例来说,假设用户A需要pymysql=1.0.2版本,而用户B需要pymysql=1.0.3版本,那么我们该如何应对呢?

当我们考虑将系统安装的Python的pymysql三方库依赖升级至1.0.3版本时,这必然会对用户A产生潜在的风险和影响。这就迫使我们需要一种解决方案,能够满足不同用户或租户对不同Python库版本的需求,而不会相互干扰。这也是本文要深入阐述的关键内容。

解决方案就在于Python虚拟环境。通过创建独立的、隔离的Python运行环境,我们可以满足不同用户对Python库的需求,而无需牵扯到底层服务器已安装的Python版本。这使得每个用户或租户能够拥有自己的Python环境,可以在其中自由地安装、更新和管理所需的Python库,而不会干扰其他用户。

二、原理

2.1、Python依赖关系

在 Python 的生态系统中,依赖分为标准库和三方库两种,它们在开发过程中起着不同的作用:

  1. 标准库是由Python官方团队维护和发布的一组模块和库。这些模块和库包含了丰富的工具和功能,涵盖了文件I/O、字符串操作、网络通信、数学计算、数据结构、日期时间处理等方面。这些模块是Python解释器的一部分,在安装Python时会一同安装。标准库的模块常被广泛应用于各类Python应用程序中,因为它们保证了跨平台的兼容性和稳定性。
  2. 三方库则是由Python社区贡献和维护的库,这些库提供了丰富的功能,包括数据处理、Web开发、科学计算等领域。与标准库不同,三方库不随Python解释器的安装而自动包含,需要使用包管理工具如pip来安装。它们的多样性和灵活性为开发者提供了更广泛的选择空间,可以根据特定需求轻松获取所需功能。
  3. 安装目录在文件系统中,Python标准库的模块位于安装目录下的Lib目录内,而三方库则被安装在Lib/site-packages目录下。这种结构有助于开发者在系统中准确找到和管理所需的库,如下图:

在这里插入图片描述

2.2、虚拟环境依赖原理

Python虚拟环境实现了一种高效的依赖隔离机制,其核心原理在于充分利用系统Python的标准库,而三方库则被完全隔离存储于虚拟环境中的独立目录。

在Python虚拟环境中,标准库的管理与系统Python的标准库实现共享。这意味着虚拟环境不会单独复制系统Python的标准库,而是通过指向系统Python标准库的符号链接进行访问。这种方式确保了虚拟环境中的Python标准库与系统Python保持同步,同时避免了资源浪费。

与标准库不同,三方库在虚拟环境中得到了彻底的隔离。每个虚拟环境都拥有自己独立的Lib/site-packages目录,用于存储安装的三方库。通过这种机制,不同虚拟环境内的项目可以安全地使用不同版本或不同组合的三方库,而无需担心相互干扰或产生冲突,如下图:

在这里插入图片描述

三、实战

3.1、venvpyvenvvirtualenv 区别

创建Python虚拟环境通常有三种常用的命令:venvpyvenvvirtualenv

  1. venv:
    • venv 是 Python 3.3 及以上版本自带的标准库模块。
    • 这个命令能够快速创建Python虚拟环境,并提供了一种简洁而有效的方式来隔离项目的依赖关系。
    • 使用方法是通过运行 python -m venv myenv 来创建一个名为 myenv 的虚拟环境。
  2. pyvenv:
    • pyvenv 是 Python 3.3 之前版本中的一个命令,用于创建虚拟环境。
    • 它的功能与 venv 类似,但在较新的Python版本中已经不再推荐使用,并被 venv 替代。
  3. virtualenv:
    • virtualenv 是一个第三方库,能够在 Python 2.x 和 3.x 版本中使用。
    • 与前两者不同,virtualenv 提供了更多的灵活性和高级选项,可以为用户提供更加定制化的虚拟环境。
    • 通过运行 pip install virtualenv 安装后,可以使用命令 virtualenv myenv 创建一个名为 myenv 的虚拟环境。

总体来说,venvvirtualenv 是创建Python虚拟环境最常用的方式。venv 是Python自带的标准库模块,提供了基本的虚拟环境功能,而 virtualenv 则提供了更多定制和高级选项,能够满足更复杂的需求。pyvenv 已在较新版本的Python中被弃用,建议使用更为推荐的 venv

3.2、创建虚拟环境

先通过执行 venv 指令来创建一个 虚拟环境: 运行此命令将会生成一个目标目录(如果其父目录不存在,也会被创建)

root@b3268f2479f8:~# python3 -m venv /usr/local/env/myenv
root@b3268f2479f8:~# ll /usr/local/env/myenv
total 16
drwxr-xr-x 2 root root 4096 Dec 15 06:48 bin
drwxr-xr-x 3 root root 4096 Dec 15 06:48 include
drwxr-xr-x 3 root root 4096 Dec 15 06:48 lib
lrwxrwxrwx 1 root root    3 Dec 15 06:48 lib64 -> lib
-rw-r--r-- 1 root root  177 Dec 15 06:48 pyvenv.cfg

同时在目标目录中会放置一个名为pyvenv.cfg的文件。这个配置文件内包含了一个home键,指向运行此命令的 系统 Python 命令位置:

root@b3268f2479f8:~# cat /usr/local/env/myenv/pyvenv.cfg
home = /usr/local/bin
include-system-site-packages = false
version = 3.12.1
executable = /usr/local/bin/python3.12
command = /usr/local/bin/python3 -m venv /usr/local/env/myenv

此外,命令还会在目标目录中创建一个bin子目录,其中包含了 Python 可执行文件的拷贝或符号链接。同时,还会建立一个初始为空的lib/pythonX.Y/site-packages子目录,用于存放虚拟环境执行pip安装的三方库:

3.3、激活虚拟环境

激活一个虚拟环境可以通过source 一个脚本来实现。在 linux 系统上,该脚本位于 bin 目录下的 activate。这个激活操作的效果是将该目录添加到你的 PATH 环境变量中。这样,当你运行 python 时,系统会调用虚拟环境的 Python 解释器,使你能够轻松运行虚拟环境中安装的脚本,而无需使用完整的路径信息,如下:

激活虚拟环境后,命令行头部会显示虚拟环境的名称(myenv)以提示你当前所处的环境,此时执行pip依赖三方库命令:由于虚拟环境被激活,故此时执行的pip命令会因为环境变量使用该虚拟环境中的pip,而不是系统全局的pip

可以看到kafka依赖只存在于虚拟环境三方库目录,系统环境不受影响。

3.4、停用虚拟环境

停用(或退出)虚拟环境只需执行 deactivate 命令即可。执行该命令后,命令行提示符中不再显示虚拟环境的名称,并且系统的 $PATH 环境变量会回到默认状态,如下:

# 激活时$PATH
(myenv) root@b3268f2479f8:/usr/local/env/myenv# echo $PATH
/usr/local/env/myenv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# 停用时$PATH
(myenv) root@b3268f2479f8:/usr/local/env/myenv# deactivate
root@b3268f2479f8:/usr/local/env/myenv# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

3.5、直接使用虚拟环境

其实激活虚拟环境并不是必须的,因为你可以直接指定特定虚拟环境的Python解释器完整路径来调用Python。更进一步地说,安装在虚拟环境中的所有脚本也可以在不激活虚拟环境的情况下运行,例如:

此外,如果我们要使用虚拟环境的Python来执行python脚本,我们可以在脚本中包含一个以“井号叹号”开头的行,用来指定虚拟环境的Python解释器路径,例如 #!/<path-to-venv>/bin/python。这意味着无论$PATH的取值如何,该脚本都将使用指定的解释器来运行。

以下是一个示例,假设有一个名为example_script.py的脚本,它指定了虚拟环境中Python解释器的路径:

#!/usr/local/env/myenv/bin/python

def main():
    print("这个脚本安装在虚拟环境中,并使用指定的解释器运行!")

if __name__ == "__main__":
    main()

在这个示例中,#!/usr/local/env/myenv/bin/python 表示脚本将使用位于虚拟环境中的Python解释器来执行。

因此,无需激活虚拟环境,该脚本都将使用特定虚拟环境中的解释器来运行。

3.6、删除虚拟环境

由于Python虚拟环境被视为可以随时丢弃和重建的,你可以直接使用 rm 命令(在Unix或类Unix系统中)来删除整个虚拟环境目录。

假设你的虚拟环境名称为 myenv,你可以在命令行中执行以下命令来删除:

root@b3268f2479f8:/usr/local/env# rm -rf myenv/

请注意,这样的删除操作是不可逆的。删除后,虚拟环境中的所有数据和安装的包都将被永久移除。确保你删除的是正确的虚拟环境路径,以免不小心删除了重要数据。

3.5、虚拟环境迁移部署

由于安装在虚拟环境中的脚本不要求必须激活该虚拟环境,因此它们的“井号叹号”行会包含虚拟环境的绝对路径,如下图:

这种情况下,虚拟环境是不可移植的。为确保便捷地重建虚拟环境,你应当提供简便的方式(例如,若你已准备好需求文件 requirements.txt,可使用虚拟环境的 pip 执行 pip install -r requirements.txt 命令来安装虚拟环境所需的所有软件包)如下:

# 创建requirements.txt
(myenv) root@b3268f2479f8:/usr/local/env/myenv# pip freeze > requirements.txt
(myenv) root@b3268f2479f8:/usr/local/env/myenv# cat requirements.txt
certifi==2023.11.17
charset-normalizer==3.3.2
confluent-kafka==2.3.0
idna==3.6
requests==2.31.0
urllib3==2.1.0

如果因某种原因你需要将虚拟环境移动到新位置,你应当在目标位置上重新创建虚拟环境,并删除旧位置上的虚拟环境。同样,如果你移动了虚拟环境的上级目录,也应在新位置上重新创建虚拟环境。否则,安装在该虚拟环境中的软件包可能无法正常运行。

举例来说,假设你在 /usr/local/env/myenv 目录下创建了一个虚拟环境,现在你想将它移动到 /usr/local/env/myenv2/ 目录。你可以执行以下步骤:

  1. 在目标位置上重建虚拟环境

    python3 -m venv /usr/local/env/myenv2  # 使用 venv 创建一个名为 myenv 的新虚拟环境
    
  2. 使用 requirements.txt 安装所需的软件包

    cd /usr/local/env/myenv2
    source bin/activate  # 激活新的虚拟环境
    pip install -r /usr/local/env/myenv/requirements.txt
    

这样可以确保在新位置重新创建了虚拟环境,并安装了相同的软件包。移动虚拟环境时,务必谨慎操作以确保其中的软件包能够正常工作。

四、结语

Python虚拟环境是Python开发者不可或缺的利器。它为开发者提供了一个独立、隔离的Python工作空间,使得不同项目之间的依赖管理更为灵活和高效。通过虚拟环境,开发者可以轻松地控制Python版本和安装的库,确保项目开发的稳定性和可靠性。

五、相关资料

python虚拟环境官方文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/249795.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构第 6 章 ④】- 用 C 语言实现图的深度优先搜索遍历和广度优先搜索遍历

目录 一、深度优先搜索 1.1 - 深度优先搜索遍历的过程 1.2 - 深度优先搜索遍历的算法实现 二、广度优先搜索 2.1 - 广度优先搜索遍历的过程 2.2 - 广度优先搜索遍历的算法实现 和树的遍历类似&#xff0c;图的遍历也是从图中某一顶点出发&#xff0c;按照某种方法对图中所…

算法leetcode|92. 反转链表 II(rust重拳出击)

文章目录 92. 反转链表 II&#xff1a;样例 1&#xff1a;样例 2&#xff1a;提示&#xff1a;进阶&#xff1a; 分析&#xff1a;题解&#xff1a;rust&#xff1a;go&#xff1a;c&#xff1a;python&#xff1a;java&#xff1a; 92. 反转链表 II&#xff1a; 给你单链表的…

基于itextpdf的java读取和更新pdf表单域字段值功能

基于itextpdf的java读取和更新pdf表单域字段值功能 执行结果为&#xff1a; Hello World! keytopmostSubform[0].Page1[0].qhjc[0] keytopmostSubform[0].Page1[0].qhmc[0] keytopmostSubform[0].Page1[0].cqzh[0] keytopmostSubform[0].Page1[0].fm_year[0] keytopmostSubf…

springboot整合vue,将vue项目整合到springboot项目中

将vue项目打包后&#xff0c;与springboot项目整合。 第一步&#xff0c;使用springboot中的thymeleaf模板引擎 导入依赖 <!-- thymeleaf 模板 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-t…

yolov5单目测距+速度测量+目标跟踪

要在YOLOv5中添加测距和测速功能&#xff0c;您需要了解以下两个部分的原理&#xff1a; 单目测距算法 单目测距是使用单个摄像头来估计场景中物体的距离。常见的单目测距算法包括基于视差的方法&#xff08;如立体匹配&#xff09;和基于深度学习的方法&#xff08;如神经网…

锂电池是什么

锂电池 电工电气百科 文章目录 锂电池前言一、锂电池是什么二、锂电池的类别三、锂电池的作用原理总结前言 锂电池相比其他类型的电池具有许多优点,包括高能量密度、长寿命、低自放电率和较低的内阻等。这些特性使它成为现代电子设备和电动交通工具中首选的能源储存技术。然而…

互联网加竞赛 python+opencv+机器学习车牌识别

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于机器学习的车牌识别系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;4分工作量&#xff1a;4分创新点&#xff1a;3分 该项目较为新颖&#xff0c;适…

热烈庆祝安徽普朗膜技术有限公司参加2024济南生物发酵展

公司自2004年注册成立以来主要业务领域主要有以乳酸、氨基酸、抗生素为主的发酵液的提取分离&#xff1b;醋、酱油发酵产品的产品升级&#xff0c;果汁、茶饮料等天然产物提取的除菌和澄清过滤&#xff1b;低聚木糖、低聚果糖、果葡糖浆、高果糖浆等过滤、纯化、浓缩&#xff1…

java SSM酒店客房管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM酒店客房管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代 码和数据库&#xff0c;系统主要采…

机器学习的12个基础问题

1.阐述批归一化的意义 算法 1&#xff1a;批归一化变换&#xff0c;在一个 mini-batch 上应用于激活 x。 批归一化是一种用于训练神经网络模型的有效方法。这种方法的目标是对特征进行归一化处理&#xff08;使每层网络的输出都经过激活&#xff09;&#xff0c;得到标准差为 …

Mr. Cappuccino的第66杯咖啡——解决MacOS中终端下的中文乱码问题

解决MacOS中终端下的中文乱码问题 中文乱码问题解决方法 中文乱码问题 解决方法 查看Mac使用的是哪个shell echo $SHELL我这里使用的是zsh&#xff0c;将配置添加到.zshrc配置文件中 vi ~/.zshrc 输入i进入编辑模式 esc退出编辑模式 :wq# UTF-8 export LANGen_US.UTF-8加载配…

Excel中MATCH和INDEX函数的用法详解,以及Vlookup的数组用法

match函数 目的&#xff1a;查询函数&#xff0c;范围单元格中搜索特定的项&#xff0c;然后返回该项在此区域中的相对位置。 For example:让 match 去【隔壁办公室】找【老张】 Match 回复&#xff1a;【老张】坐在【隔壁办公室】第【四】个座位上 公式&#xff1a;【 mat…

驱动框架之_gpio_and_pinctrl-设备树的修改

1&#xff1a;设置设备树中的信息 安装“ Pins_Tool_for_i.MX_Processors_v6_x64.exe ”后运行&#xff0c;打开 IMX6ULL 的配置文件“ MCIMX6Y2xxx08.mex ”&#xff0c;就可以在 GUI 界面中选择引脚&#xff0c; 配置它的功能&#xff0c;这就可以自动生成 Pinctrl 的子节…

Linux查看进程的详细信息

使用top找到进程id使用下面命令查看进程的详细信息 systemctl status 17878

Microsoft visual studio 2013卸载方法

1、问 题 Microsoft visual studio 2013 无法通过【程序与功能】卸载 2、解决方法 使用微软的Microsoft visual studio 2013 专用卸载工具 工具下载链接&#xff1a;https://github.com/Microsoft/VisualStudioUninstaller/releases 或 链接&#xff1a;https://pan.baidu.c…

服务器挖矿木马识别与清理

一、什么是挖矿木马 挖矿木马会占用CPU进行超频运算,从而占用主机大量的CPU资源,严重影响服务器上的其他应用的正常运行。黑客为了得到更多的算力资源,一般都会对全网进行无差别扫描,同时利用SSH爆破和漏洞利用等手段攻击主机。部分挖矿木马还具备蠕虫化的特点,在主机被成…

华为ensp-无线小型wlan配置教程

实验拓扑图&#xff1a; 实验平台&#xff1a;ENSP510 实验设备&#xff1a;Centered Cloud、AC6005、AP4030、STA、Cellphone vlan范围划分 vlan 101 : 10.23.101.1/24 vlan 100 : 10.23.100.1/24实验步骤&#xff1a; 一、创建VLAN100、101配置端口类型 [AC1]vlan batch 100…

Python日期范围按旬和整月以及剩余区间拆分

昨天见到了一个比较烧脑的问题&#xff1a; 咋一看可能理解问题比较费劲&#xff0c;可以直接看结果示例&#xff1a; 当然这个结果在原问题上基础上有一定改进&#xff0c;例如将同一天以单个日期的形式展示。 如何解决这个问题呢&#xff1f;大家可以先拿测试用例自己试一下…

Android 移动端编译 cityhash动态库

最近做项目&#xff0c; 硬件端 需要 用 cityhash 编译一个 动态库 提供给移动端使用&#xff0c;l 记录一下 编译过程 city .cpp // // Created by Administrator on 2023/12/12. // // Copyright (c) 2011 Google, Inc. // // Permission is hereby granted, free of charg…

Seata客户端启动流程

自动装配 Springboot启动的时候会将下面这几个类进行自动装配 SeataRestTemplateAutoConfiguration(装载拦截器) 这里会装配 SeataRestTemplateInterceptor (Seata的拦截器) Configuration(proxyBeanMethods false) public class SeataRestTemplateAutoConfiguration {B…