整体说明
- 打包本地项目为的 pip 包时,可以使用
pip install .命令 - 执行
pip install .命令时,Python 包管理工具pip会根据当前目录中的setup.py文件来安装包- 这个过程涉及多个步骤,包括解析包的元数据、处理依赖关系、构建和安装包等
- 安装的内容包括包的所有模块、数据文件、编译文件以及命令行工具
- 默认情况下,只安装核心依赖,可选依赖需要用户显式指定
构建一个包的步骤
第一步:解析和构建
- 解析
setup.py(setup.py的详细示例见附录):pip首先会查找并解析当前目录中的setup.py文件- 读取包的元数据(如包名、版本、作者信息等)和安装选项(如
install_requires、extras_require等)
- 构建包:
pip会使用setuptools或distutils来构建包- 包的构建包括编译C扩展(如果存在)、处理包内的数据文件等
- 生成一个源代码分发包(Source Distribution,简称
sdist)或一个二进制分发包(Binary Distribution,简称wheel)
第二步:处理依赖
- 安装核心依赖
pip会根据setup.py中的install_requires列表安装包的核心依赖- 这些依赖是包运行所必须的
- 可选依赖
- 如果用户在命令中指定了可选依赖组(如
pip install .[dev]),pip会安装对应的extras_require可选依赖 - 否则,默认情况下不会安装
extras_require中的可选依赖
- 如果用户在命令中指定了可选依赖组(如
第三步:安装包**
- 导入包和模块
pip会将构建好的包安装到Python环境的site-packages目录中- 包中的所有模块和子包都会被导入
- 包数据文件
- 如果
setup.py中设置了include_package_data=True或指定了package_data,这些数据文件也会被安装
- 如果
- 命令行工具
- 如果
setup.py中定义了entry_points,对应的命令行工具会被安装并注册
- 如果
第四步:打包内容
- 包和模块
- 所有通过
packages或find_packages()指定的包和模块
- 所有通过
- 数据文件
- 通过
package_data或include_package_data指定的额外数据文件
- 通过
- 编译文件
- 如果包中包含 C/C++ 扩展模块,这些模块会被编译并打包
附录:setup.py 文件的示例
setup.py文件是 Python 项目中用于定义包的元数据、依赖关系及其他安装相关信息的脚本setup.py文件主要通过setuptools或distutils库来实现包的配置和分发
setup.py 文件示例
setup.py文件基本结构示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36from setuptools import setup, find_packages
setup(
name="package_name", # 包名
version="0.1.0", # 版本号
author="Author Name", # 作者
author_email="author@example.com", # 作者邮箱
description="A short description", # 简短描述
long_description=open("README.md").read(), # 长描述(通常从README文件导入)
long_description_content_type="text/markdown", # 长描述类型(如Markdown)
url="https://github.com/username/repo", # 项目URL
packages=find_packages(), # 自动发现并包含所有包
classifiers=[ # 分类标签(如开发状态、受众、许可证)
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.6', # Python版本要求
install_requires=[ # 安装依赖
"requests>=2.25.0",
"numpy",
],
extras_require={ # 可选依赖(如开发、测试)
"dev": ["pytest", "sphinx"],
},
entry_points={ # 命令行工具入口
"console_scripts": [
"mycommand=mypackage.module:function",
],
},
include_package_data=True, # 包含包内数据文件
package_data={ # 指定包数据文件
"mypackage": ["data/*.dat"],
},
zip_safe=False, # 是否允许打包为zip文件
)
主要内容和功能说明
- 元数据:
name: 包的名称version: 包的版本号,通常遵循语义版本规范(如MAJOR.MINOR.PATCH)author和author_email: 作者的姓名和联系邮箱description和long_description: 包的简短和详细描述url: 项目的主页或代码仓库地址
- 包和模块:
packages: 指定需要包含的包列表,通常使用find_packages()自动发现package_data: 指定需要包含的非代码文件(如数据文件、模板等)
- 依赖管理:
install_requires: 安装包时需要满足的依赖列表extras_require: 可选依赖,按功能分组(如开发依赖、测试依赖)
- Python 版本:
python_requires: 指定包支持的Python版本范围
- 分类标签:
classifiers: 用于描述包的特性和分类,帮助用户和工具识别包的适用性
- 命令行工具:
entry_points: 定义包提供的命令行工具及其入口函数
- 数据文件:
include_package_data: 是否包含包内的额外数据文件
- 打包选项:
zip_safe: 指定包是否可以安全地打包为zip文件
附录:setup.py 中的 extras_require 使用
在
setup.py中定义的extras_require提供了一种机制,可以按需安装额外的依赖项extras_require允许定义一些可选的依赖组,比如开发依赖、测试依赖等举例来说,前面附录小节的示例中
extras_require中定义了一个名为 “dev” 的组和对应的依赖默认情况下 ,安装包时不会自动安装
extras_require中定义的可选依赖项- 直接使用
pip install .或pip install package_name安装包即可 - 在这种情况下,只有
install_requires中定义的核心依赖会被安装
- 直接使用
安装可选依赖,以 安装 “dev” 组的可选依赖 为例:
使用
pip安装时,可以通过在包名后加上[dev]来指定安装这些可选依赖1
pip install .[dev]
如果包已经发布到PyPI或其他包管理平台,可以使用以下命令:
1
pip install package_name[dev]