python 的版本、依赖包、虚拟环境管理

news/2025/1/18 18:33:51/文章来源:https://www.cnblogs.com/jasongrass/p/18678663

我并不是 python 开发者,但突然对这个话题感兴趣,所以就和 AI 聊了起来,以下是一些聊天笔记。
注意,这里可能有部分内容是过时或者错误的,以官方文档或者实际效果为准。


在电脑上安装 python 之后,就可以直接在控制台执行 python 脚本了。但此时有两个问题,
1 python 的版本是固定的,如果有多个项目,不同的项目可能需要不同的 python 版本。
2 全局状态下,python 的包管理是会冲突的,同一个包,只能有一个版本存在,如果不同项目依赖于不同的版本的包,就会有冲突。

🍉 python 版本管理

解决第一个问题的工具,是 python 版本管理,如 pyenv

pyenv/pyenv: Simple Python version management

不过 pyenv 并不支持 Windows 系统,Windows 系统可以使用 pyenv-win/pyenv-win: pyenv for Windows.

类似的,对于 node.js,也有 nvm, n 这样的版本管理工具

pyenv-win

不推荐通过 scoop 安装,安装的版本似乎是有问题的。直接使用 powershell 脚本安装。

pyenv-win/docs/installation

# 安装
Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/pyenv-win/install-pyenv-win.ps1" -OutFile "./install-pyenv-win.ps1"; &"./install-pyenv-win.ps1"# 升级
&"${env:PYENV_HOME}\install-pyenv-win.ps1"

PS scoop 自带了 python 版本管理功能,不过功能比较简单
Switching Ruby, Python and PHP Versions · ScoopInstaller/Scoop Wiki

🍉 python 虚拟环境

解决第二个问题的方案,是虚拟环境。相关工具 virtualenvvenv(python 3.3 之后自带)

虚拟环境关联了 python 版本和安装的依赖包。虚拟环境是一个全局的概念,在同一时刻,电脑上只有一个虚拟环境是激活状态,此时,在这个环境下安装的包,都被这个环境管理。
如果有另一个项目依赖不同的 python 版本和依赖包,则切换 python 版本后,在那个版本创建一个新的虚拟环境。

因为虚拟环境是一个全局的概念,项目A和项目B的虚拟环境不一致的话,切换项目时,需要先手动切换到对应的虚拟环境。(当然,也可以使用工具进行自动切换)

在没有激活任何虚拟环境时,就处于默认的全局环境中。

在使用 poetry 进行项目管理时,可以创建不影响全局的虚拟环境,仅影响当前项目。本质上,是 poetry 拦截了执行进程的环境变量等相关设置。
所以,换句话说,需要使用 poetry 来执行脚本。如果在命令行窗口直接使用 python 命令来执行脚本,使用的还是全局的配置。

感受如下 python .\__init__.pypoetry run python .\__init__.py 的区别。

python .\__init__.pyPython 可执行文件路径: C:\Users\jgrass\.pyenv\pyenv-win\versions\3.13.1\python.exe
Python 版本: 3.13.1
完整版本信息: 3.13.1 (tags/v3.13.1:0671451, Dec  3 2024, 19:06:28) [MSC v.1942 64 bit (AMD64)]
操作系统平台: Windows
模块搜索路径:C:\Users\jgrass\Desktop\practice\python\my_project1\my_project1C:\Users\jgrass\.pyenv\pyenv-win\versions\3.13.1\python313.zipC:\Users\jgrass\.pyenv\pyenv-win\versions\3.13.1\DLLsC:\Users\jgrass\.pyenv\pyenv-win\versions\3.13.1\LibC:\Users\jgrass\.pyenv\pyenv-win\versions\3.13.1C:\Users\jgrass\.pyenv\pyenv-win\versions\3.13.1\Lib\site-packages
poetry run python .\__init__.pyPython 可执行文件路径: C:\Users\jgrass\Desktop\practice\python\my_project1\.venv\Scripts\python.exe
Python 版本: 3.13.1
完整版本信息: 3.13.1 (tags/v3.13.1:0671451, Dec  3 2024, 19:06:28) [MSC v.1942 64 bit (AMD64)]
操作系统平台: Windows
模块搜索路径:C:\Users\jgrass\Desktop\practice\python\my_project1\my_project1C:\Users\jgrass\Desktop\practice\python\my_project1\.venv\Scripts\python313.zipC:\Users\jgrass\.pyenv\pyenv-win\versions\3.13.1\DLLsC:\Users\jgrass\.pyenv\pyenv-win\versions\3.13.1\LibC:\Users\jgrass\.pyenv\pyenv-win\versions\3.13.1C:\Users\jgrass\Desktop\practice\python\my_project1\.venvC:\Users\jgrass\Desktop\practice\python\my_project1\.venv\Lib\site-packagesC:\Users\jgrass\Desktop\practice\python\my_project1
import sys
import platform# 获取 Python 解释器的可执行文件路径
python_executable_path = sys.executable
print(f"Python 可执行文件路径: {python_executable_path}")# 获取 Python 版本信息
python_version = platform.python_version()
print(f"Python 版本: {python_version}")# 获取完整的版本信息,包括编译器和构建时间
python_version_info = sys.version
print(f"完整版本信息: {python_version_info}")# 获取系统平台信息
system_platform = platform.system()
print(f"操作系统平台: {system_platform}")# 获取 Python 搜索模块的路径(即 sys.path)
python_module_search_paths = sys.path
print("模块搜索路径:")
for path in python_module_search_paths:print(f"  {path}")

所以,在引入虚拟环境这个概念之后,搞清楚在当前执行环境,究竟是在哪个环境,使用的是哪个解释器就很关键。

python 版本管理于虚拟环境的关系

在使用 pyenv 和虚拟环境(如 virtualenvvenv)的组合时,Python 的版本通常由虚拟环境本身来决定,而不是由全局的 Python 版本控制工具(如 pyenv)直接影响。

场景举例:

使用 pyenv 设置当前 Python 的版本为 3.7。
创建一个虚拟环境 env1。
激活虚拟环境 env1。
使用 pyenv 将全局或本地 Python 版本切换到 3.11。
在激活的虚拟环境 env1 中检查 Python 的版本。

结果分析:
在这种情况下,当你激活虚拟环境 env1 时,虚拟环境会使用它创建时指向的 Python 二进制文件(即创建虚拟环境时的 Python 版本)。这意味着:

虚拟环境 env1 是使用 Python 3.7 创建的,因此激活虚拟环境后,命令行中的 python 版本仍然是 3.7,不会受到 pyenv 切换全局或本地 Python 版本的影响。
虚拟环境是一个独立的沙盒环境,它会以创建时的 Python 解释器为基础,因此切换 pyenv 的版本不会改变虚拟环境的行为。
也就是说,当激活 env1 后检查 Python 的版本,输出的应该是:Python 3.7.x

为什么会这样?

虚拟环境的本质:

虚拟环境在创建时会复制(或者软链接)当前 Python 解释器的核心文件到虚拟环境目录下,并将虚拟环境的 bin(Linux/Mac)或 Scripts(Windows)目录调整为优先搜索路径。
因此,当虚拟环境被激活时,系统会优先使用虚拟环境内的 Python 解释器,而不是全局版本。

pyenv 的作用范围:

pyenv 管理的是全局或者当前目录下的 Python 版本,而虚拟环境则是一个独立的环境。一旦激活虚拟环境,pyenv 对 Python 版本的控制就会被虚拟环境屏蔽。

如果你想验证上述行为,可以尝试以下步骤:

# 使用 pyenv 设置 Python 版本为 3.7
pyenv shell 3.7# 查看当前 Python 版本,应该是 3.7
python --version# 创建虚拟环境
python -m venv env1# 激活虚拟环境
source env1/bin/activate  # Linux/Mac
# 或
env1\Scripts\activate     # Windows# 再次查看 Python 版本,应该是 3.7
python --version# 退出虚拟环境
deactivate# 切换 pyenv 的版本到 3.11
pyenv shell 3.11# 在未激活虚拟环境时,Python 版本应该是 3.11
python --version# 重新激活虚拟环境 env1
source env1/bin/activate  # Linux/Mac
# 或
env1\Scripts\activate     # Windows# 检查激活虚拟环境后的 Python 版本,应该仍是 3.7
python --version

总结:虚拟环境会记录创建时的 Python 版本,并在激活后使用该版本的解释器。即使你用 pyenv 切换了全局或本地的 Python 版本,虚拟环境的 Python 版本不会受到影响。

🍉 python 包管理

虽然有了虚拟环境,可以解决不同项目之间依赖的冲突问题,但是对于一个具体的项目,如何管理其依赖呢?比如前端有 package.json,rust 有 cargo.toml,C# 有 csproj 文件。

Python 的方案有点多,不同的工具,使用的是不同的方式。

Python 的包管理方案随着时间的推移不断发展,以适应不断变化的需求和生态系统。以下是从历史演进路径介绍的不同方案:

1. requirements.txt

requirements.txt 是最早、最常用的 Python 项目依赖管理方式。这个文件简单地列出了项目中所有需要的依赖包及其版本。

requests==2.25.1
flask==1.1.2

2. setup.py

setup.py 是用于创建可分发包(distributable package)的标准文件。它不仅可以用于管理项目依赖,还可以定义项目的元数据和打包信息。

// setup.py
from setuptools import setupsetup(name='my_project',version='0.1',install_requires=['requests==2.25.1','flask==1.1.2',],
)

安装依赖:

pip install .

3.Pipfile 和 Pipfile.lock

PipfilePipfile.lock 是由 Pipenv 引入的,用于替代 requirements.txt,提供更现代化、更安全的依赖管理方式。Pipfile 记录项目的依赖,而 Pipfile.lock 锁定依赖的具体版本,确保环境一致性。

Pipfile 文件示例:

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true[packages]
requests = "*"
flask = "*"[dev-packages]
pytest = "*"[requires]
python_version = "3.9"

4. pyproject.toml

pyproject.toml 是 PEP 518 引入的标准文件,旨在统一 Python 项目的配置。它不仅可以用于依赖管理,还可以配置构建工具(如 setuptoolspoetry)和其他工具。

pyproject.toml 文件示例:

[tool.poetry]
name = "my_project"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"][tool.poetry.dependencies]
python = "^3.9"
requests = "^2.25.1"
flask = "^1.1.2"[tool.poetry.dev-dependencies]
pytest = "^6.2.2"[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

5. Conda 环境

Conda 是一个跨平台的包和环境管理系统,支持 Python 以及其他编程语言。Conda 提供了强大的依赖管理和环境隔离功能,特别适用于数据科学和机器学习项目。

使用方法
创建环境并安装依赖:

environment.yml 文件示例:

name: myenv
channels:- defaults
dependencies:- python=3.9- requests=2.25.1- flask=1.1.2- pip:- pytest==6.2.2

python 包管理小结

不同的包管理方案适用于不同的场景和需求:

  • requirements.txt:简单、广泛使用,适合小型项目。
  • setup.py:适合创建可分发包的项目,管理依赖和元数据。
  • PipfilePipfile.lock:现代化依赖管理,适合需要锁定依赖版本的一致性项目。
  • pyproject.toml:统一配置文件,适合使用现代构建工具(如 poetry)的项目。
  • Conda 环境:强大的包和环境管理,适合数据科学和机器学习项目。

在搜索 pipenvpoetry 时,感觉 poetry 优势很明显。

在使用 pipenv 或者 poetry 时,使用它们安装依赖包时,会自动为项目创建虚拟环境,在切换项目时,需要执行 pipenv shell 或者 poetry shell 来激活虚拟环境。

pipenv 或者 poetry 等工具,底层都是使用 virtualenvvenv 来管理虚拟环境。

🍉 工具的使用

pyenv 是 python 版本管理工具,与其他工具是独立的。

pipenvpoetryConda 这个工具的功能是重合的,都集成了包管理,虚拟环境管理等功能,同一个项目,使用一个就可以。

pipx

pypa/pipx: Install and Run Python Applications in Isolated Environments

一个 python 全局工具包安装管理工具,使用 pipx 安装 poetry

pipx install poetry
installed package poetry 2.0.1, installed using Python 3.13.1These apps are now globally available- poetry.exe
⚠️  Note: 'C:\Users\jgrass\.local\bin' is not on your PATH environment variable. These apps will not be globallyaccessible until your PATH is updated. Run `pipx ensurepath` to automatically add it, or manually modify your PATHin your shell's config file (e.g. ~/.bashrc).
done! ✨ 🌟 ✨

然后运行 pipx ensurepath,将 C:\Users\jgrass\.local\bin 添加到环境变量,这样才可以使用 poetry

Success! Added C:\Users\jgrass\.local\bin to the PATH environment variable.Consider adding shell completions for pipx. Run 'pipx completions' for instructions.You will need to open a new terminal or re-login for the PATH changes to take effect. Alternatively, you can source
your shell's config file with e.g. 'source ~/.bashrc'.Otherwise pipx is ready to go! ✨ 🌟 ✨

这里还提示,运行 pipx completions 添加代码补全功能。

pipx 安装的工具不受 pyenv 切换版本的影响,因为 pipx 在独立的虚拟环境中管理这些工具,并通过固定路径将它们链接到系统的 PATH 环境变量中。
这确保了无论你切换到哪个 Python 版本,pipx 管理的工具都能正常工作。

pipx 安装工具时使用的 Python 版本是你在运行 pipx install 命令时的系统默认 Python 版本。
它不受当前激活的虚拟环境影响,但你可以通过 pyenv 或其他方式切换系统的 Python 版本来影响 pipx 创建的虚拟环境。

可以使用 pipx list 来查看 pipx 安装的工具,以及其基于的 Python 版本。
如果要在新的 Python 版本中安装工具,在使用 pyenv 切换版本之后,可以使用 pipx reinstall <tool> 重新安装工具。

poetry

使用 poetry 创建项目 poetry new my_project1

进入项目目录,执行 poetry install 自动创建一个虚拟环境,并安装 pyproject.toml 文件中指定的所有依赖项(如果有的话)。

Creating virtualenv my-project1-lE7ezTdX-py3.13 in C:\Users\jgrass\AppData\Local\pypoetry\Cache\virtualenvs
Updating dependencies
Resolving dependencies... (0.1s)Writing lock fileInstalling the current project: my-project1 (0.1.0)

poetry env info 可以快速查看当前项目的虚拟环境信息,包括路径和是否激活
poetry env info --path 可以直接查看虚拟环境的路径
poetry env list 查看虚拟环境列表

配置 virtualenvs.in-projecttrue 后,可以更直观地管理虚拟环境

Poetry 默认会将虚拟环境存储在用户目录下的 .cache/pypoetry/virtualenvs/ 中,但你也可以更改其行为,使虚拟环境直接创建在项目目录下。可以通过以下命令设置:

poetry config virtualenvs.in-project true,设置之后,如果之前已经创建了这个项目的虚拟环境,则需要先删除 poetry env remove python
然后重新安装 poetry env use python / poetry install

配置完成后,虚拟环境将会创建在项目目录内的 .venv 文件夹中。这样可以更方便地找到虚拟环境。

poetry 入门完全指南 | 正心全栈编程

poetry shell 命令默认不可用,在 Poetry 2 被移除了,需要安装插件。
Commands | Documentation | Poetry - Python dependency management and packaging made easy

可以使用 poetry env use python 来进入独立的 shell 虚拟环境,并使用 exit 退出。

在使用 Poetry 时,激活的虚拟环境不会影响全局的虚拟环境设置。Poetry 会为每个项目创建独立的虚拟环境,这些虚拟环境是独立于全局 Python 环境的。

在全局命令行中,你可以通过以下几种方法检查当前是否激活了虚拟环境,以及激活的是哪个虚拟环境:

检查环境变量:激活虚拟环境时,通常会设置 VIRTUAL_ENV 环境变量来指示当前正在使用的虚拟环境。你可以通过以下命令检查这个变量:

echo $VIRTUAL_ENV

如果输出为空,则没有激活虚拟环境。如果输出的是一个路径,则该路径指向当前激活的虚拟环境。

使用 whichwhere 命令:

你可以检查当前使用的 Python 解释器路径:

which python# 或在 Windows 上:
where python

如果输出的路径指向虚拟环境中的 Python 解释器,则表示当前激活了虚拟环境。

使用 Poetry 命令:Poetry 提供了一些命令来管理和检查虚拟环境。你可以使用以下命令查看当前项目的虚拟环境路径:

poetry env info --path

这将输出当前项目的虚拟环境路径。如果没有激活虚拟环境,则不会有输出。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

How Far Are We to GPT-4V? Closing the Gap to Commercial Multimodal Models with Open-Source Suites

InternVL1.5: 更强的视觉编码器,动态处理高分辨率图像,高质量的双语数据集。主要内容 对标商业模型,提出InternVL1.5。更强的视觉编码器(InternViT-6B),动态处理高分辨率图像(将图像分成448*448的tails,最高支持4K分辨率),高质量的双语数据集(显著提高了OCR和中文相…

在ByteTrack中使用DanceTrack数据集

从github下载DanceTrack项目(不包含数据集,数据集需要单独下载) git clone https://github.com/DanceTrack/DanceTrack.git修改convert_dance_to_coco.py中数据集的位置,然后运行,将数据集格式转化为coco格式将DanceTrack中ByteTrack中的相关文件拷贝到ByteTrack项目中 Danc…

EdgeRunner

WSL2配置代理 - Sherioc - 博客园 EdgeRunner论文解读环境配置显示报错是FlashAttention需要CUDA 11.7及以上版本。 之前FriNet是CUDA 11.1,重新装了CUDA 11.8(并且已经改好设置),但是还是构建失败。 2025/1/18,又能构建了……(very slow)代码 首先注意到了License 1、l…

1月15日证书来啦!工信部人才交流中心PostgreSQL中级/高级认证

恭喜在2024年11月参加工信部人才交流中心PostgreSQL管理员PG中级和PG高级认证考试的各位同学,之前已经能够查到电子版的证书,现在纸质版证书也到啦! 部分学员电子证书:部分学员纸质证书:............ 为什么选择工信人才PostgreSQL认证: 发证机构:工信部人才交流中心属于…

「NOIP2024」 树上查询

update 2024/12/28 题目描述 给定一棵树,每次询问区间 \([l,r]\) 的 \[\max_{l \le l \le r \le r \land r - l + 1 \ge k}\text{dep}_ {\text{LCA*}(l, r)} \]引理证明 先来证两个区间 \(\text{LCA}\) 的引理: 对于 \(\text{LCA} \{ l, l + 1, \dots r\}\) 我们有 \(\text{L…

Flask Web开发实战:入门、进阶与原理解析PDF免费下载

PythonWeb框架Flask开发团队成员撰写,内容全面,从基础知识到进阶实战,再到源码分析,提供完善的Flask学习路径适读人群 :本书适合了解Python基本语法,想要自己动手做网站的编程人员;熟悉Python。想要从事Python Web开发的后端工程师、运维工程师和爬虫工程师;香葱Django…

CMU 15-445 23Fall总结

注:编译、测试之前运行sudo sysctl vm.mmap_rnd_bits=28 BusTubs architecture: 1. Query Processing (查询处理层) 负责将输入的 SQL 查询转化为可执行的物理查询计划。Parser(解析器):将输入的 SQL 字符串解析为抽象语法树 (AST),检查 SQL 语法是否合法。 Binder(绑定器…

从数据到模型,足球预测方法解析

在足球赛事范畴内,比赛结局始终蕴含着诸多不确定性,而这恰恰构成了足球独特的魅力要素。对于广大球迷而言,尝试预测足球比赛的最终结果,向来是一项极具吸引力与挑战性的活动。 近年来,伴随数据科学以及机器学习技术的迅猛发展,足球预测领域发生了深刻变革。这些先进技术为…

传奇三虚拟机服务端-客户端win10可用

论坛转来的,还没有实验架设 传奇3 虚拟机服务端一键架设。。。好吧,三键架设,据说WIN10可玩服务端启动稍微有点步骤,还算简单吧QQ截图20200414142743.jpg (73.53 KB, 下载次数: 0)下载附件2020-4-14 14:41 上传QQ截图20200414142828.jpg (74.73 KB, 下载次数: 0)下载附件20…

THREE.js学习笔记9——Materials

这一小节主要学习材质 材质用于为几何物理模型的每个可见像素添加颜色。 Materials are used to put a color on each visible pixel of the geometries. 决定每个像素颜色的算法是在程序中编写的,称为着色器。 Three.js 具有许多带有预制着色器的内置材料。 Algorithms that …

[HarekazeCTF2019]baby_rop2(read的libc)

一个normal的栈溢出,没有system和binsh,为ret2libc 这里也没有常见的write和puts,所以我们用read泄露libc基址,并使用printf打印read的地址 这里注意printf的第一个参数必须是格式字符串,即Welcome to the Pwn World again(地址为0x0400770,第二个参数设为read_got(got表…

Living-Dream 系列笔记 第93期

最大流 EK & Dinic本文讲解 EK & Dinic 算法。 最大流 最大流的模型:特别注意:这个流量上限不是单次流量不超过它,而是多次的总和不超过它。 EK 显然这个问题是可以使用 dfs 解决的,但是效率低下。 考虑如下的图。我们发现 dfs 有可能走了 \(S \to A \to B \to T\)…