全面讲解python包的构建与安装,让你看懂pip install的报错(pip build whl setuptools)
解决pip install的报错。详细介绍python包的构建与安装,关于pip build wheel setuptools poetry的相关知识。相信读者在使用pip配置环境的时候总会遇到一些莫名其妙的问题,看到一堆乱七八糟不知所云的输出日志,其中包含各种各样的文件后缀和命令格式,总是稀里糊涂的混过去也不是个办法。下面围绕介绍python包的创建和安装介绍一些概念,以及它们之间的关系,让读者
目录
全文总结
相信读者在使用pip配置环境的时候总会遇到一些莫名其妙的问题,看到一堆乱七八糟不知所云的输出日志,其中包含各种各样的文件后缀和命令格式,总是稀里糊涂的混过去也不是个办法。下面围绕介绍python包的创建和安装介绍一些概念,以及它们之间的关系,让读者不再感到困惑,在看到报错信息、网络上和AI给的出的解决方案时知道它们在说什么。本文使用人工智能辅助完成。
- pip
- build
- wheel
- setuptools
- poetry
- pyproject.toml
总结:首先讲解一下它们的关系,之后会细说它们各自的功能。看文章的内容时如果遇到问题,可以回顾一下这里。先引入几个概念:
- build backend
定义:Build Backend 是负责实际构建和打包 Python 项目的工具或库。
作用:处理项目的编译、打包、测试等具体任务。
示例:setuptools、Poetry、flit 、hatch等 - build frontend
定义:Build Frontend 是调用 Build Backend 的工具,负责解析项目配置文件(如 pyproject.toml)并调用相应的 Build Backend。
作用:提供统一的接口,使得用户可以使用不同的 Build Backend 而无需关心具体的实现细节。
示例:pip、build 工具等。 - 配置文件:例如setup.py, pyproject.toml。用于辅助打包和构建
- 两种文件格式:tar.gz, .whl,ip 会优先尝试安装 .whl 文件,因为 .whl 文件是预编译的二进制分发包,安装速度更快且更可靠。如果找不到合适的 .whl 文件,pip 会退而求其次,下载并安装 tar.gz 文件(源代码分发包)。也可以手动安装到本地之后执行
pip install pkg.whl,安装在你的Python环境中!
流程
配置文件:开发者编写pyproject.toml或setup.py,并对项目做初始化
项目打包:使用python -m build,poetry build,或者python setup.py pkg,构建.whl和tar.gz文件
测试:开发者运行 pip install . 或者pip install pkg.whl下载到本地进行测试
发布python包:发布到PyPI,使用twine或者poetry
用户命令:用户运行 pip install package从PyPI网站上下载程序。
前端解析:pip 或 build 工具读取 pyproject.toml 文件。
调用后端:根据 build-backend 配置,调用 setuptools或者Poetry来执行构建任务。
pip
下载Python的时候自带pip包,pip是用来管理python包的工具,无论在什么目录下执行pip install package,pip会自动把该package安装到当前(虚拟)环境中的Lib/site-packages中。python有一个网站PyPI,用来管理python包的发行,你也可以自己写一个包发行到该网站上。
安装和构建的过程
- 下载分发包
查找分发包:pip 会在 PyPI(Python Package Index)或其他指定的索引服务器上查找与请求的包名称和版本匹配的分发包。
优先选择 .whl 文件:pip 会优先选择 .whl 文件,因为它们是预编译的二进制分发包,安装速度快且可靠。
如果找不到 .whl 文件:pip 会下载 tar.gz 文件(源代码分发包)。 - 构建项目
- 对于 .whl 文件:
pip 会直接解压 .whl 文件到目标目录。
.whl 文件通常包含预编译的二进制文件和纯 Python 代码,因此不需要额外的构建步骤。 - 对于 tar.gz 文件:
pip 会解压 tar.gz 文件到一个临时目录。
pip 会读取 pyproject.toml 文件(如果存在),从中获取构建系统的信息。
使用 build 工具:如果 pyproject.toml 文件中指定了 build-backend,pip 会调用相应的构建工具(如 setuptools 或 Poetry)来构建项目。
使用 setup.py:如果项目中没有 pyproject.toml 文件或 build-backend 指定为 setuptools,pip 会调用 setup.py 脚本来构建项目。
- 安装项目
- 安装 .whl 文件:
pip 会将解压后的文件直接复制到目标目录(通常是 site-packages 目录)。
pip 会处理依赖项的安装,确保所有依赖项都已安装。 - 安装 tar.gz 文件:
构建工具(如 setuptools 或 Poetry)会生成一个 .whl 文件或直接安装到目标目录。
pip 会处理依赖项的安装,确保所有依赖项都已安装。
pip install .
pip install . 会查找当前目录下的 setup.py 文件或 pyproject.toml 文件来获取包的元数据和构建配置。这个命令把你写的Python包安装在本地。
- 使用
setup.py:pip会运行python setup.py install来安装包。setup.py文件中定义的依赖项会被自动安装。
- 使用
pyproject.toml:pip会使用pyproject.toml文件中定义的构建系统(如setuptools、flit、poetry等)来构建和安装包。pyproject.toml文件中定义的依赖项会被自动安装。
build
1. 什么是 build 库?
build 是一个独立的工具,用于构建 Python 包。build 库的主要目标是提供一个简单、一致的接口,用于构建各种类型的 Python 包,而不需要关心底层的构建系统细节。它简化了 Python 包的构建过程,特别是在处理基于 pyproject.toml 文件的项目时。
2. 主要功能
- 构建包:从
pyproject.toml文件中读取构建配置,并生成.whl(轮子文件)和.tar.gz(源分发文件)。 - 依赖管理:自动处理构建过程中所需的依赖项。
- 隔离构建环境:默认情况下,
build会在一个隔离的虚拟环境中进行构建,以避免与全局环境冲突。 - 支持多种构建后端:可以使用不同的构建后端(如
setuptools、flit、poetry等)。
3. 安装
你可以使用 pip 安装 build 库:
pip install build
4. 使用 build 库构建 Python 包
4.1 pyproject.toml 文件
pyproject.toml 文件是 build 库的核心配置文件,用于定义包的构建配置。
假设你有一个包含 pyproject.toml 文件的项目目录,你可以使用以下命令来构建包:
python -m build
这将会生成两个文件:
dist/<your_project>-<version>.whl:轮子文件,用于快速安装。dist/<your_project>-<version>.tar.gz:源分发文件,包含项目的源代码。
5. 常用命令
5.1 构建所有文件
python -m build
这将会生成 .whl 和 .tar.gz 文件。
5.2 仅构建轮子文件
python -m build --wheel
这将会生成 .whl 文件。
5.3 仅构建源分发文件
python -m build --sdist
这将会生成 .tar.gz 文件。
5.4 指定输出目录
python -m build --outdir ./dist
这将会将生成的文件输出到指定的目录。
6. 示例项目结构
一个典型的 build 项目结构如下:
my_project/
├── src/
│ └── my_project/
│ ├── __init__.py
│ └── main.py
├── tests/
│ ├── __init__.py
│ └── test_main.py
├── pyproject.toml
├── README.md
└── LICENSE
wheel
1. 什么是 .whl 文件?
.whl 文件本质是一种 ZIP 归档文件,是 Python 的一种二进制分发格式,包含预编译的 Python 包及其依赖项,用于分发预编译的 Python 包。这种格式可以显著加快包的安装速度,因为安装时不需要重新编译源代码。
2. .whl 文件的结构
一个典型的 .whl 文件包含以下几个部分:
- 纯 Python 包:包含
.py文件和.pyc文件。 - 预编译的扩展模块:包含
.so(Linux 和 macOS)或.pyd(Windows)文件。 - 元数据文件:包含包的元数据信息,如包名、版本、依赖项等。
3. .whl 文件的优势
- 安装速度快:预编译的
.whl文件可以直接安装,无需编译过程,大大缩短了安装时间。 - 兼容性强:
.whl文件可以包含平台特定的二进制文件,使得同一个包可以在不同平台上使用不同的.whl文件。 - 依赖管理:
.whl文件包含包的依赖项信息,pip会自动解析并安装这些依赖项,确保所有依赖项都正确安装。。
4. .whl 文件的命名规则
.whl 文件的命名遵循一定的规则,以便 pip 能够正确识别和安装。命名格式如下:
{distribution}-{version}(-{build tag})?-{python tag}-{abi tag}-{platform tag}.whl
{distribution}:包的名称。{version}:包的版本号。{build tag}(可选):构建标记,用于区分同一版本的不同构建。{python tag}:Python 版本标签,表示该.whl文件适用于哪个 Python 版本。{abi tag}:ABI(Application Binary Interface)标签,表示该.whl文件使用的 ABI。{platform tag}:平台标签,表示该.whl文件适用于哪个平台。
例如,numpy-1.21.0-cp39-cp39-win_amd64.whl 表示:
numpy:包的名称。1.21.0:包的版本号。cp39:Python 3.9。cp39:ABI 标签,表示使用的是 CPython 3.9 的 ABI。win_amd64:平台标签,表示适用于 Windows 64 位平台。
5. 如何生成 .whl 文件
你可以使用 wheel 库来生成 .whl 文件。假设你有一个包含 setup.py 文件的项目目录,可以使用以下命令生成 .whl 文件:
python setup.py bdist_wheel
这将会在 dist 目录下生成一个 .whl 文件。
此外也可以用我们上面介绍过的方法python -m build --wheel
6. 如何安装 .whl 文件
你可以使用 pip 来安装 .whl 文件。假设你有一个 .whl 文件 example-1.0.0-py3-none-any.whl,可以使用以下命令安装:
pip install example-1.0.0-py3-none-any.whl
7. 常见的 .whl 文件来源
- PyPI:Python 包索引(PyPI)是 Python 包的主要分发渠道,许多包都有
.whl文件可供下载。 - 第三方仓库:一些组织和个人可能会提供自己的
.whl文件仓库,例如 Anaconda 的conda-forge仓库。
8. 示例
假设你有一个包含 setup.py 文件的项目目录,setup.py 文件内容如下:
from setuptools import setup, find_packages
setup(
name='my_project',
version='0.1.0',
packages=find_packages(),
install_requires=[
'numpy',
'matplotlib'
],
author='John Doe',
author_email='john.doe@example.com',
description='A sample Python project',
)
你可以使用以下命令生成 .whl 文件:
python setup.py bdist_wheel
生成的 .whl 文件将位于 dist 目录下,例如 my_project-0.1.0-py3-none-any.whl。
egg
1. 什么是 .egg 文件?
.egg 文件是一种归档文件,用于分发 Python 包。由 setuptools 引入。虽然现在 .whl 文件更为常用,但在某些情况下,你仍然可能会遇到 .egg 文件。它类似于 .zip 文件,但包含了额外的元数据信息。.egg 文件可以包含以下内容:
- Python 源代码:
.py文件。 - 编译后的字节码:
.pyc文件。 - 资源文件:如配置文件、数据文件等。
- 元数据:如包的名称、版本、依赖项等。
2. .egg 文件的特点
- 自包含:
.egg文件是一个自包含的归档文件,包含了一个 Python 包的所有必要文件和元数据。 - 可执行:某些
.egg文件可以作为可执行文件直接运行。 - 可安装:可以使用
easy_install或pip安装.egg文件。 - 元数据丰富:包含详细的包元数据,如名称、版本、依赖项等。
3. 生成 .egg 文件
你可以使用 setuptools 生成 .egg 文件。假设你有一个包含 setup.py 文件的项目目录,可以使用以下命令生成 .egg 文件:
python setup.py bdist_egg
这将会在 dist 目录下生成一个 .egg 文件。
4. 安装 .egg 文件
4.1 使用 easy_install
easy_install 是 setuptools 提供的一个工具,可以用来安装 .egg 文件。例如:
easy_install path/to/package-1.0-py2.7.egg
4.2 使用 pip
虽然 pip 更推荐使用 .whl 文件,但它也支持安装 .egg 文件。例如:
pip install path/to/package-1.0-py2.7.egg
5. .egg 文件的结构
.egg 文件是一个 ZIP 归档文件,包含以下目录和文件:
EGG-INFO目录:包含包的元数据信息。PKG-INFO:包的基本信息,如名称、版本等。requires.txt:包的依赖项列表。entry_points.txt:定义的入口点(如可执行脚本)。top_level.txt:包的顶级模块列表。
- 包的源代码和资源文件:如
my_package/__init__.py、my_package/data.txt等。
6. 与 .whl 文件的比较
-
.egg文件:- 由
setuptools引入。 - 包含丰富的元数据。
- 可以作为可执行文件直接运行。
- 逐渐被
.whl文件取代。
- 由
-
.whl文件:- 由 PEP 427 定义。
- 二进制分发格式,安装速度快。
- 不包含可执行文件,但可以包含预编译的扩展模块。
- 更广泛地被现代工具(如
pip)支持。
setuptools
1. 什么是 setuptools?
setuptools 是一个用于管理 Python 包的开发和分发的工具集。它扩展了标准库中的 distutils,提供了更多的功能,使得包的创建、分发和安装变得更加容易和灵活。setuptools 是许多现代 Python 包的基础,包括 pip 和 wheel。
2. 主要功能
- 包管理:
setuptools提供了创建和管理 Python 包的工具。 - 依赖管理:自动处理包的依赖项,确保所有依赖项都正确安装。
- 动态发现包:自动发现项目中的所有包,而不需要手动列出。
- 入口点:定义和管理可执行脚本和插件。
- 版本控制:支持复杂的版本控制和自动化的版本号管理。
- 测试支持:集成测试框架,支持单元测试和集成测试。
- 跨平台支持:支持多种操作系统和 Python 版本。
3. 安装
你可以使用 pip 安装 setuptools:
pip install setuptools
4. 使用 setuptools 创建 Python 包
4.1 手动创建一个 setup.py 文件
setup.py 文件是 setuptools 的核心配置文件,用于定义包的元数据和构建选项。以下是一个典型的 setup.py 文件示例:
from setuptools import setup, find_packages
setup(
name='my_project',
version='0.1.0',
author='John Doe',
author_email='john.doe@example.com',
description='A sample Python project',
long_description=open('README.md').read(),
long_description_content_type='text/markdown',
url='https://github.com/johndoe/my_project',
packages=find_packages(),
classifiers=[
'Programming Language :: Python :: 3',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
],
python_requires='>=3.6',
install_requires=[
'numpy',
'matplotlib',
],
entry_points={
'console_scripts': [
'my_script=my_project.cli:main',
],
},
)
4.2 参数说明
name:包的名称。version:包的版本号。author:作者姓名。author_email:作者邮箱。description:包的简短描述。long_description:包的长描述,通常从README.md文件中读取。long_description_content_type:长描述的格式,通常是text/markdown。url:包的项目主页 URL。packages:包的列表,通常使用find_packages()自动发现。classifiers:分类器,用于在 PyPI 上对包进行分类。python_requires:指定支持的 Python 版本。install_requires:包的依赖项列表。entry_points:定义可执行脚本和插件。
5. 常用命令
5.1 构建源分发包
python setup.py sdist
这将会生成一个 .tar.gz 文件,位于 dist 目录下。
5.2 构建轮子文件
python setup.py bdist_wheel
这将会生成一个 .whl 文件,位于 dist 目录下。
5.3 安装包
pip install .
这将会从当前目录安装包。
5.4 上传包到 PyPI
python -m twine upload dist/*
这将会使用 twine 工具将包上传到 PyPI。
6. 其他功能
6.1 动态发现包
find_packages() 函数会自动发现项目中的所有包,而不需要手动列出:
from setuptools import find_packages
packages = find_packages()
6.2 入口点
entry_points 用于定义可执行脚本和插件。例如,定义一个命令行脚本:
entry_points={
'console_scripts': [
'my_script=my_project.cli:main',
],
}
这将会生成一个名为 my_script 的可执行脚本,调用 my_project.cli 模块中的 main 函数。
6.3 测试支持
setuptools 集成了测试框架,支持单元测试和集成测试。例如,运行所有测试:
python setup.py test
7. 示例项目结构
一个典型的 setuptools 项目结构如下:
my_project/
├── my_project/
│ ├── __init__.py
│ └── cli.py
├── tests/
│ ├── __init__.py
│ └── test_my_project.py
├── setup.py
├── README.md
└── MANIFEST.in
pyproject.toml
1. 什么是 pyproject.toml?
pyproject.toml 是一个 TOML(Tom’s Obvious, Minimal Language)格式的配置文件,用于定义 Python 项目的构建系统和依赖项。它主要用于以下几个方面:
- 构建配置:定义项目的构建系统和所需的依赖项。
- 项目元数据:定义项目的元数据,如名称、版本、作者、依赖项等。
- 工具配置:配置项目中使用的各种工具,如 linters、formatters、test runners 等。
2. 文件结构
pyproject.toml 文件通常包含以下几个部分:
2.1 [build-system] 部分
[build-system] 部分定义了项目的构建系统和所需的依赖项。这是 PEP 518 标准的一部分。
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
requires:一个列表,包含构建项目所需的依赖项。这些依赖项将在构建过程中自动安装。build-backend:指定构建后端的入口点。常见的构建后端有setuptools.build_meta、flit_core.buildapi、poetry.core.masonry.api等。
2.2 [project] 部分
[project] 部分定义了项目的元数据。这是 PEP 621 标准的一部分。
[project]
name = "my_project"
version = "0.1.0"
description = "A sample Python project"
readme = "README.md"
license = { file = "LICENSE" }
authors = [
{ name = "John Doe", email = "john.doe@example.com" }
]
requires-python = ">=3.6"
dependencies = [
"numpy",
"matplotlib"
]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
name:项目的名称。version:项目的版本号。description:项目的简短描述。readme:项目的长描述文件路径。license:项目的许可证信息,可以是一个字符串或一个对象(包含文件路径)。authors:项目的作者信息,可以是一个或多个对象。requires-python:指定支持的 Python 版本。dependencies:项目的依赖项列表。classifiers:分类器,用于在 PyPI 上对项目进行分类。
2.3 [tool.<tool_name>] 部分
[tool.<tool_name>] 部分用于配置项目中使用的各种工具。每个工具都有自己的配置部分,例如 [tool.black] 用于配置 Black 代码格式化工具。
[tool.black]
line-length = 88
target-version = ['py36', 'py37', 'py38', 'py39']
line-length:每行的最大长度。target-version:目标 Python 版本。
3. 示例 pyproject.toml 文件
以下是一个完整的 pyproject.toml 文件示例:
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "my_project"
version = "0.1.0"
description = "A sample Python project"
readme = "README.md"
license = { file = "LICENSE" }
authors = [
{ name = "John Doe", email = "john.doe@example.com" }
]
requires-python = ">=3.6"
dependencies = [
"numpy",
"matplotlib"
]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
[tool.black]
line-length = 88
target-version = ['py36', 'py37', 'py38', 'py39']
[tool.isort]
profile = "black"
[tool.flake8]
max-line-length = 88
ignore = ["E501"]
[tool.pytest.ini_options]
addopts = "--cov=my_project"
4. 使用 pyproject.toml 文件
4.1 构建项目
你可以使用 build 库来构建项目:
pip install build
python -m build
这将会生成 .whl 和 .tar.gz 文件,位于 dist 目录下。
4.2 安装项目
你可以使用 pip 来安装项目:
pip install .
这将会从当前目录安装项目。
4.3 发布项目
你可以使用 twine 工具将项目发布到 PyPI:
pip install twine
python -m twine upload dist/*
5. 常见工具配置
5.1 Black
Black 是一个代码格式化工具,可以自动格式化代码。
[tool.black]
line-length = 88
target-version = ['py36', 'py37', 'py38', 'py39']
5.2 isort
isort 是一个代码排序工具,可以自动排序导入语句。
[tool.isort]
profile = "black"
5.3 flake8
flake8 是一个代码风格检查工具,可以检查代码的风格和错误。
[tool.flake8]
max-line-length = 88
ignore = ["E501"]
5.4 pytest
pytest 是一个测试框架,可以用于编写和运行测试。
[tool.pytest.ini_options]
addopts = "--cov=my_project"
6.创建pyproject.toml 文件
生成 pyproject.toml 文件有几种方法,具体取决于你的需求和项目类型。以下是一些常见的方法:
1. 使用 setuptools 和 wheel
如果你已经有一个 setup.py 文件,可以使用 setuptools 和 wheel 自动生成 pyproject.toml 文件。
步骤:
-
安装
setuptools和wheel:pip install setuptools wheel -
创建
pyproject.toml文件:
你可以手动创建一个基本的pyproject.toml文件,或者使用setuptools的setup.py文件来自动生成。基本的
pyproject.toml文件:[build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta" -
使用
setuptools生成pyproject.toml:
你可以使用setuptools的setup.py文件来自动生成pyproject.toml文件。虽然setuptools本身不直接提供生成pyproject.toml的命令,但你可以手动将setup.py中的信息迁移到pyproject.toml文件中。
2. 使用 poetry
poetry 是一个非常强大的工具,可以自动生成和管理 pyproject.toml 文件。
步骤:
-
安装
poetry:curl -sSL https://install.python-poetry.org | python3 - -
初始化项目:
进入你的项目目录,运行poetry init命令来生成pyproject.toml文件。cd your_project_directory poetry initpoetry init会引导你填写项目的基本信息,如名称、版本、描述、作者、依赖项等。 -
编辑
pyproject.toml文件:
生成的pyproject.toml文件会包含项目的基本配置。你可以根据需要进一步编辑。示例
pyproject.toml文件:[tool.poetry] name = "my_project" version = "0.1.0" description = "A sample Python project" authors = ["John Doe <john.doe@example.com>"] license = "MIT" readme = "README.md" packages = [{include = "my_project"}] [tool.poetry.dependencies] python = "^3.6" numpy = "^1.21.0" matplotlib = "^3.4.0" [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api"
3. 使用 flit
flit 是另一个轻量级的工具,可以自动生成和管理 pyproject.toml 文件。
步骤:
-
安装
flit:pip install flit -
初始化项目:
进入你的项目目录,运行flit init命令来生成pyproject.toml文件。cd your_project_directory flit initflit init会引导你填写项目的基本信息,如名称、版本、描述、作者、依赖项等。 -
编辑
pyproject.toml文件:
生成的pyproject.toml文件会包含项目的基本配置。你可以根据需要进一步编辑。示例
pyproject.toml文件:[build-system] requires = ["flit_core >=3.2,<4"] build-backend = "flit_core.buildapi" [project] name = "my_project" version = "0.1.0" description = "A sample Python project" authors = [ { name = "John Doe", email = "john.doe@example.com" } ] dependencies = [ "numpy", "matplotlib" ]
4. 使用 hatch
hatch 是一个现代化的 Python 包管理工具,可以自动生成和管理 pyproject.toml 文件。
步骤:
-
安装
hatch:pip install hatch -
初始化项目:
进入你的项目目录,运行hatch new命令来生成pyproject.toml文件。cd your_project_directory hatch new .hatch new .会引导你填写项目的基本信息,如名称、版本、描述、作者、依赖项等。 -
编辑
pyproject.toml文件:
生成的pyproject.toml文件会包含项目的基本配置。你可以根据需要进一步编辑。示例
pyproject.toml文件:[project] name = "my_project" version = "0.1.0" description = "A sample Python project" authors = [ { name = "John Doe", email = "john.doe@example.com" } ] dependencies = [ "numpy", "matplotlib" ] [build-system] requires = ["hatchling"] build-backend = "hatchling.build"
参考
下面两个都是非常好的教程
Python程序打包指南:手把手教你一步步完成
将python库下载到本地安装—Pypi官网wheel版本选择详解—小白详解版
Python Packaging User Guide: Glossary
Python Packaging User Guide: Project Summaries
更多推荐


所有评论(0)