🏗️

Python 中的依赖安装

Tag
Python
Slug
python-dep
Created
Apr 10, 2023
环境:macOS@13 / Python3 / pip@22 / npm@9 / conda@23

概述

npm (Node Package Manager) 是 Node.js 官方包管理工具,本文将将通过与 JS 的依赖管理作比较的方式,介绍 Python 中的依赖安装和背后的原理。
pip(Package Installer for Python) 是 Python 官方提供的依赖管理工具,可以类比为 npm 之于 Node,通过执行 pip 相关的一系列命令,就可以完成依赖安装。
功能
npm
pip
安装软件包
npm install <package>
pip install <package>
安装项目依赖
npm install
pip install -r requirements.txt

差异

默认安装位置

通过 npm 安装的依赖,默认会安装下项目根目录的 node_modules文件夹下,每个依赖都是独立存在。而 pip安装的依赖,默认安装在全局的 Python 环境中,这样就可以会导致项目之间的依赖冲突。为了解决这一问题,开发者一般通过创建虚拟环境的方式来创建独立的项目环境。
创建虚拟环境的工具有很多,这里以 conda 为例:
# 创建名为 my_project_env 的虚拟环境 conda create --name my_project_env # 会在 /Users/<username>/anaconda3/envs/ 中创建一个 my_project_env 文件夹 # 激活虚拟环境 conda activate my_project_env # 在此之后通过 pip 安装的所有依赖都会进入 # my_project_env/lib/python<version>/site-packages
Python 的依赖默认会安装在全局,应该也是历史遗留问题。当时设计的时候,就没有考虑到多项目之间会有依赖版本冲突的问题,从而后续需要通过创建虚拟环境的方式解决。

依赖文件

npm 使用 package.json 文件来管理描述依赖信息,并且会生成一个 package-lock.json 的文件来控制依赖的版本,版本号遵循 Semantic Versioning 规范。
pip 通常使用 requirements.txt 文件来列出项目依赖,虽然支持程度的版本控制,但是并未完全遵循语义版本规范,因为 pip需要兼容多种不同的版本约定,也算是个历史包袱了。

二进制文件和平台支持

npm 主要用于 JavaScript 项目,大部分软件包与平台无关,所以不需要在不同的平台上编译成二进制文件。
但是 Python 软件包可能包含 CC++ 或语言编写的拓展模块,这些模块需要在不同架构、操作系统的目标平台上进行编译,因此需要处理包含平台相关二进制文件的软件包。

总结

本文以 JS 依赖管理为基础,介绍了 Python 的依赖安装及原理。主要差异包括:默认安装位置,依赖文件,以及二进制文件和平台支持。