Python 包管理

模块&导入

Python中,任何一个 .py 文件都可以被看作一个模块。可以通过 import 语句用于将其他模块的功能引入到当前文件中。

# 导入整个模块
import database_driver

# 导入并设置别名
import database_driver as db

# 导入特定内容(也可设置别名)
from database_driver import mysql_driver as mysql

# 导入模块中所有非下划线开头的内容(会污染命名空间 慎重使用)
from database_driver import *

项目复杂后,单文件无法很好的组织内容。由此,通过文件夹将模块内容分包组织。在 Python3.3 之前,每个包必须创建 __init__.py 文件作为标识(后续不强制但是建议保留)。

__init__.py 的作用:

  • 标记为包,新版本不强制但是为了保证兼容性和清晰性,建议仍然创建
  • 初始化,其中的代码在包被导入时会自动执行,可以完成一些初始化的操作
  • 简化导入,将包深处的函数代码暴露对外,方便调用

分包之后,代码结构更加清晰,但是包内的模块很可能还是互相依赖,同时和全局的包区分,包内可以通过 绝对导入相对导入 来引入包内模块。

  • 绝对导入: 总是从项目根目录开始
  • 相对导入: 只能包内使用,由 ... 分别标识当前目录跟上级目录

包管理

标准&手动流程

包管理器

Python 默认使用 PyPI 作为官方仓库,最常用的包管理工具是 pip

# 安装包
pip install requests

# 指定版本
pip install "requests==2.28.1"
pip install "requests>=2.25.0"

# 卸载包
pip uninstall requests

# 已安装列表
pip list

# 查看详细信息
pip show requests

貌似 pip 已经可以支持我们安装各种环境库依赖了,但是其还存在一个问题,以这种方式直接安装的库,会被放在一个全局的环境中,且被所有项目共享。于是乎导致了很容易版本冲突,以及复杂的依赖关系。

对此,给出的解决方案就是虚拟环境。

虚拟环境

虚拟环境可以为每一个项目创建一个独立、隔离的Python环境,你在其中安装和配置的依赖只属于这个项目而不会污染扩散到全局。

Python3.3开始,venv 模块为创建虚拟环境的标准工具。

# 创建 一般都是 .venv 方便IDE 识别
python3 -m venv .venv

# 激活环境
source venv/bin/activate

# window环境
.venvScriptsactivate

# 成功后命令行前面会有 (venv)

其中 .venv 为虚拟环境名,创建完成后该文件夹内会包含独立的Python解释器和包安装目录。后续就可以正常安装依赖了。

但是当你的项目引入了很多的第三方包的时候,那项目的其他成员也需要安装配置相关的依赖库。于是,我们需要一种方式来记录所有的项目需要的依赖。

依赖管理

最早期的方式是通过 pip freeze 将当前环境中的所有依赖重定向写入到一个 requirements.txt 文件。

# 打印依赖重定向到目标文件
pip freeze > requirements.txt

# 导入依赖
pip install -r requirements.txt

这种方式存在的缺陷是,其无法分辨什么是项目中的直接依赖,什么是由依赖产生的间接依赖。如果项目变得复杂,引入的依赖很多,pip 如果需要移除一个依赖,其并不能很好的整理到所有的相关依赖而导致一些间接依赖无法被卸载。

更现代一点的官方标准方案是使用 pyproject.toml 文件替换requirements.txt

[project]
name = "test"
version = "0.0.1"
dependencies  = [
    "requests==2.28.1"
]

此时只需要将直接依赖加入到 dependencies 列表中即可。

# 当前目录安装创建环境
# -e 指定将源代码通过链接加入到虚拟环境 而非拷贝
pip install -e .

Conda 宇宙

conda 更像是一个运行环境,可以使用其方便切换各种 python 环境,在遇到复杂环境依赖时,是一个非常省心的方式。

Anaconda 是一个打包的集合,里面预装好了 conda、某个版本的 python以及各种包。

  • Anaconda
  • conda
安装

这里由于不需要安装Anaconda 包含的那么多包,因此选择MiniConda。安装流程如下:

# 创建文件夹 用户目录
mkdir -p ~/miniconda3
# 下载安装脚本
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
# 执行脚本
bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
# 删除安装脚本
rm ~/miniconda3/miniconda.sh
# 激活环境
source ~/miniconda3/bin/activate
# 推出虚拟环境
conda deactivate
# 初始化
conda init --all
# 校验
conda -V
常用命令小记

一些常用的conda命令。

  • conda 相关
# conda 安装、环境、渠道等信息
conda info

# 清理缓存
# --all 删除所有缓存
# --packages 只删除安装包的缓存
# --tarballs 删除 .tar.bz2 包缓存
conda clean --all

# 配置conda
# 添加渠道
conda config --add channels conda-forge
# 删除渠道
conda config --remove channels defaults

  • 环境管理
# 创建环境 
# --name 指定环境名
# --python 指定python版本
# --channel / -c 指定源渠道
conda create --name env_name

# 激活环境
conda activate env_name

# 退出当前环境
conda deactivate

# 列出所有环境
conda env list 
conda info --envs

# 删除环境
# --all 删除整个环境
conda remove --name env_name --all

# 导出环境
# 导出环境到 environment.yml 
conda env export > environment.yml

# 通过 yml 文件创建环境
# -f 指定环境yml文件路径
# --name 指定环境名
conda env create -f environment.yml --name new_env

# 克隆环境
conda create --name new_env --clone old_env
  • 包管理
# 安装包
# -c 指定渠道
conda install pkg_name
conda install pkg_name=version

# 更新包
conda update pkg_name

# 卸载包
conda remove pkg_name

# 查看已安装的包
# --explicit 列出安装包的精确版本列表
conda list

# 搜索包
# -c 指定渠道 
# 可以指定版本号 pkg_name=version
conda search pkg_name

# 自定义构建包
# 需要当前目录有一个 meta.yaml 文件描述包的构建信息
conda build .

其他社区方案

以及如果需要安装一些Python命令行应用,可以使用 pipx(需要 Python3.6以上版本),它会为每个应用单独创建隔离环境,避免跟其他项目依赖冲突。

  • pipx github
  • pipx doc

社区中其他的方案有如 UVPoetry等。他们底层依然是使用的 venvpip,只是在此基础上进行了相关的封装。

  • UV
  • Poetry
本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]