Python打包学习

目录

  1. 什么是打包?
  2. 打包的重要性
  3. Python项目的标准目录结构
  4. 关键概念
  5. 打包工具和文件
  6. 创建和配置打包文件
  7. 版本管理
  8. 生成分发包
  9. 发布到PyPI
  10. 安装和使用包
  11. 依赖管理最佳实践
  12. 测试打包
  13. 持续集成和自动化打包
  14. 最佳实践和常见问题
  15. 资源和进一步阅读

1. 什么是打包?

打包是将你的Python项目及其依赖项组织、压缩成一个可以分发和安装的格式的过程。通过打包,你可以轻松地分享你的代码给其他开发者,或者在不同的环境中部署应用程序。

2. 打包的重要性

  • 复用性:打包使得你的代码可以被其他项目或开发者轻松使用。
  • 依赖管理:确保项目所需的库和版本得到正确管理,避免兼容性问题。
  • 分发和部署:通过打包,可以轻松地将应用部署到服务器或发布到包管理平台(如PyPI)。
  • 版本控制:管理项目的不同版本,跟踪更改,回滚到稳定版本。

3. Python项目的标准目录结构

一个标准的Python项目目录结构有助于打包和维护项目。以下是一个推荐的结构:

myproject/
├── myproject/
│   ├── __init__.py
│   ├── core.py
│   └── module.py
├── tests/
│   ├── __init__.py
│   └── test_core.py
├── docs/
│   └── ...
├── setup.py
├── setup.cfg
├── pyproject.toml
├── MANIFEST.in
├── README.md
├── LICENSE
└── requirements.txt

关键目录和文件解释:

  • myproject/:主包目录,包含项目的实际代码。
  • tests/:测试代码目录,包含单元测试。
  • docs/:项目文档目录。
  • setup.py:打包和安装的脚本。
  • setup.cfg:打包配置文件(可选)。
  • pyproject.toml:PEP 517/518定义的构建系统配置文件(现代打包推荐使用)。
  • MANIFEST.in:指定需要包含在源分发包中的非Python文件。
  • README.md:项目说明文件。
  • LICENSE:项目许可证文件。
  • requirements.txt:列出项目的依赖项。

4. 关键概念

模块 vs 包

  • 模块(Module):一个Python文件(.py),包含Python代码。
  • 包(Package):一个包含__init__.py文件的目录,包含多个模块或子包。

依赖管理

  • 依赖(Dependencies):项目所需的外部库或模块。
  • 开发依赖(Dev Dependencies):仅在开发过程中需要的库,如测试框架。

正确管理依赖项是确保项目在不同环境中一致运行的关键。

5. 打包工具和文件

setuptools

setuptools是Python最常用的打包工具,提供了创建和分发Python包所需的功能。通过setup.py文件定义包的信息、依赖项等。

wheel

wheel是一种Python包的标准分发格式,扩展名为.whl。相较于传统的.tar.gz,wheel安装更快,因为它是预编译的二进制包。

pip

pip是Python的包管理工具,用于安装、升级和卸载包。它也支持从PyPI等源进行包的发布和下载。

twine

twine是一个用于上传包到PyPI的工具,支持上传源分发包和wheel包。

pyproject.toml

pyproject.toml是PEP 517/518定义的构建系统配置文件,用于声明项目的构建依赖和构建工具。现代打包推荐使用pyproject.toml来取代传统的setup.py

6. 创建和配置打包文件

使用 setup.py

setup.py 是传统的打包脚本,用于定义包的信息和依赖项。

# setup.py
from setuptools import setup, find_packages

setup(
    name='myproject',
    version='0.1.0',
    packages=find_packages(),
    install_requires=[
        'flask>=2.0',
        'requests>=2.25',
    ],
    author='你的名字',
    author_email='你的邮箱',
    description='这是一个示例Python包',
    long_description=open('README.md', encoding='utf-8').read(),
    long_description_content_type='text/markdown',
    url='https://github.com/你的仓库/myproject',
    classifiers=[
        'Programming Language :: Python :: 3',
        'License :: OSI Approved :: MIT License',
        'Operating System :: OS Independent',
    ],
    python_requires='>=3.6',
)

使用 setup.cfg

setup.cfg 是一个可选的配置文件,可以与setup.py配合使用,或者在某些情况下完全取代setup.py

# setup.cfg
[metadata]
name = myproject
version = 0.1.0
author = 你的名字
author_email = 你的邮箱
description = 这是一个示例Python包
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/你的仓库/myproject
classifiers =
    Programming Language :: Python :: 3
    License :: OSI Approved :: MIT License
    Operating System :: OS Independent

[options]
packages = find:
install_requires =
    flask>=2.0
    requests>=2.25
python_requires = >=3.6

使用 pyproject.toml

pyproject.toml 是现代打包推荐使用的配置文件,支持多种构建系统(如setuptoolspoetryflit等)。

# pyproject.toml
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "myproject"
version = "0.1.0"
description = "这是一个示例Python包"
readme = "README.md"
requires-python = ">=3.6"
authors = [
    { name = "你的名字", email = "你的邮箱" }
]
dependencies = [
    "flask>=2.0",
    "requests>=2.25"
]
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent"
]

注意:使用pyproject.toml可以简化配置,并与现代工具更好地集成。

7. 版本管理

语义化版本

语义化版本(Semantic Versioning)是一种版本编号规范,格式为主版本号.次版本号.修订号(例如1.2.3),具体含义如下:

  • 主版本号(MAJOR):当你做了不兼容的API修改。
  • 次版本号(MINOR):当你在向下兼容的情况下添加了功能。
  • 修订号(PATCH):当你进行向下兼容的问题修正。

示例

  • 1.0.0:初始稳定版本。
  • 1.1.0:添加新功能,向下兼容。
  • 1.1.1:修复bug,向下兼容。
  • 2.0.0:不兼容的API修改。

遵循语义化版本有助于团队成员和用户理解每个版本的变化和兼容性。

8. 生成分发包

源分发包 (sdist)

源分发包包含项目的源代码和必要的文件,通常为.tar.gz格式。

生成命令

python setup.py sdist

Wheel 分发包

Wheel是Python的标准二进制分发格式,安装速度快,适用于纯Python包和包含C扩展的包。

生成命令

python setup.py bdist_wheel

现代方法(推荐使用build包)

首先安装build

pip install build

然后在项目根目录运行:

python -m build

这将生成dist/目录下的.tar.gz.whl文件。

9. 发布到 PyPI

PyPI(Python Package Index)是Python的软件包存储库,供开发者发布和分发包。

步骤:

  1. 注册PyPI账号: 前往 PyPI官网 注册一个账号。

  2. 安装Twine: Twine是用于上传包到PyPI的工具。

    pip install twine
    
  3. 生成分发包: 使用build生成源分发包和wheel包。

    python -m build
    
  4. 上传包

    twine upload dist/*
    

    这将提示你输入PyPI的用户名和密码。

注意:为了安全性,建议使用 API Token 进行身份验证,而不是直接使用密码。

10. 安装和使用包

一旦包发布到PyPI,其他开发者可以通过pip安装使用:

pip install myproject

也可以从GitHub等源安装:

pip install git+https://github.com/你的仓库/myproject.git

11. 依赖管理最佳实践

  • 指定版本范围:在install_requiresrequirements.txt中指定依赖的版本范围,避免版本冲突。

    install_requires=[
        'flask>=2.0,<3.0',
        'requests>=2.25,<3.0',
    ],
    
  • 分离开发依赖:使用requirements-dev.txtextras_require来管理开发时的依赖,如测试框架、文档生成工具。

    # setup.cfg
    [options.extras_require]
    dev =
        pytest
        sphinx
    
  • 锁定依赖版本:使用pip-toolspoetry等工具生成requirements.txt,锁定具体版本以确保环境一致性。

  • 避免依赖冗余:只列出项目真正需要的依赖,减少包的体积和潜在冲突。

12. 测试打包

在发布之前,务必测试打包过程,确保包可以正确安装和使用。

本地安装测试

在虚拟环境中安装本地生成的包进行测试。

python -m venv test-env
source test-env/bin/activate  # Linux/Mac
# test-env\Scripts\activate  # Windows

pip install dist/myproject-0.1.0-py3-none-any.whl

# 测试导入
python -c "import myproject; print(myproject.__version__)"

使用 twinecheck 命令

Twine 提供了 check 命令来验证包的完整性。

twine check dist/*

如果包有问题,twine 会提示具体的错误信息。

13. 持续集成和自动化打包

使用持续集成(CI)工具(如GitHub Actions、GitLab CI、Travis CI等)可以自动化打包和发布过程,确保每次代码更改都经过测试和打包。

示例:使用 GitHub Actions 自动打包和发布到 PyPI

  1. 在GitHub仓库中创建工作流文件

    创建 .github/workflows/python-publish.yml 文件。

    name: Publish Python Package
    
    on:
      push:
        tags:
          - 'v*.*.*'  # 触发条件:推送带有v前缀的标签,如v1.0.0
    
    jobs:
      build-and-publish:
        runs-on: ubuntu-latest
    
        steps:
          - uses: actions/checkout@v2
    
          - name: Set up Python
            uses: actions/setup-python@v2
            with:
              python-version: '3.8'
    
          - name: Install dependencies
            run: |
              python -m pip install --upgrade pip
              pip install build twine
    
          - name: Build package
            run: |
              python -m build
    
          - name: Publish to PyPI
            env:
              TWINE_USERNAME: __token__
              TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
            run: |
              twine upload dist/*
    
  2. 配置PyPI API Token

    • 在PyPI账号中生成一个API Token。
    • 在GitHub仓库的Settings > Secrets中添加一个名为PYPI_API_TOKEN的秘密,值为API Token。
  3. 发布新版本

    当你准备发布新版本时,创建一个带有v前缀的Git标签并推送。

    git tag v0.1.0
    git push origin v0.1.0
    

    GitHub Actions将自动触发工作流,生成并发布包到PyPI。

14. 最佳实践和常见问题

最佳实践

  • 保持简洁:包名应简洁、有描述性,避免与现有包冲突。
  • 包含必要文件:使用MANIFEST.in指定需要包含的非Python文件,如数据文件、文档等。
  • 编写文档:在README.md中详细说明包的功能、安装方法和使用示例。
  • 编写测试:确保包的功能通过测试,使用持续集成工具自动运行测试。
  • 使用虚拟环境:在隔离的环境中进行开发和测试,避免依赖冲突。
  • 遵循PEP规范:遵循PEP 8(代码风格)、PEP 440(版本规范)等Python社区标准。

常见问题

  • 包名已存在:
    • 选择一个独特的包名,或在名称中添加前缀/后缀。
  • 依赖冲突:
    • 通过指定版本范围和锁定依赖版本来避免。
  • 包过大:
    • 避免将不必要的文件包含在包中,使用.gitignoreMANIFEST.in进行控制。
  • 二进制扩展兼容性:
    • 对于包含C扩展的包,提供多个平台的wheel包,或者考虑使用纯Python实现。

15. 资源和进一步阅读


为什么选择 Poetry 而不是 pip

1. 更好的依赖管理

  • 锁文件(poetry.lock:Poetry 会生成一个 poetry.lock 文件,锁定所有依赖包的具体版本,确保在不同的环境中安装时的一致性。这避免了因包版本变化导致的兼容性问题。
  • 依赖解析:Poetry 使用更智能的依赖解析算法,可以更有效地解决依赖冲突,确保所有包的兼容性。

2. 项目管理一体化

  • pyproject.toml 文件:Poetry 使用 pyproject.toml 文件来集中管理项目的元数据和依赖,结构清晰,易于维护。
  • 虚拟环境管理:Poetry 可以自动为项目创建和管理虚拟环境,简化了环境配置过程。

3. 发布和打包

  • 内置发布工具:Poetry 提供了简便的命令来构建和发布包到 PyPI 等平台,简化了发布流程。

如何使用 Poetry

以下是使用 Poetry 进行包管理的基本步骤:

1. 安装 Poetry

您可以通过以下命令安装 Poetry:

curl -sSL https://install.python-poetry.org | python3 -

安装完成后,确保将 Poetry 添加到您的系统路径中,具体安装过程会在终端中提示。

2. 初始化项目

在项目目录下运行以下命令初始化 Poetry 项目:

poetry init

按照提示填写项目名称、版本、描述等信息,Poetry 会生成一个 pyproject.toml 文件。

3. 添加依赖包

使用 poetry add 命令来添加依赖包,例如安装 requests

poetry add requests

Poetry 会自动解析并安装 requests 及其依赖,并更新 poetry.lock 文件。

4. 安装所有依赖

如果已有 pyproject.tomlpoetry.lock 文件,可以使用以下命令安装所有依赖:

poetry install

5. 激活虚拟环境

Poetry 会自动为项目创建虚拟环境,您可以通过以下命令进入虚拟环境:

poetry shell

或者,您也可以在不激活虚拟环境的情况下运行命令:

poetry run python your_script.py

6. 更新依赖

要更新项目中的所有依赖包,可以使用:

poetry update

Python 打包进阶指南:结合 Wheel 包、pyproject.toml 和 Poetry

欢迎回到 Python 打包学习之旅!在上一部分,我们介绍了 Python 打包的基础知识和使用 setuptools 进行打包的流程。本篇将系统性地结合 Wheel 包pyproject.toml 文件 以及 Poetry 工具,深入探讨现代 Python 包管理与打包的方法。

目录

  1. 概述
  2. Wheel 包简介
  3. pyproject.toml 文件
  4. Poetry 简介
  5. 使用 Poetry 进行打包
  6. 示例项目实战:使用 Poetry 打包
  7. setuptools 的对比
  8. 最佳实践与建议
  9. 参考资料

1. 概述

现代 Python 包管理工具不断发展,旨在简化依赖管理、打包和发布流程。Wheel 是 Python 官方推荐的打包格式,具有安装速度快、兼容性好的优点。pyproject.toml 是 PEP 518 引入的配置文件标准,旨在统一和简化打包配置。Poetry 是一个集成了依赖管理、打包和发布功能的现代化工具,基于 pyproject.toml,旨在取代传统的 setup.pyrequirements.txt

本指南将详细介绍如何使用 Wheel、pyproject.toml 和 Poetry 来高效地管理和打包 Python 项目。


2. Wheel 包简介

什么是 Wheel 包?

Wheel 是 Python 的一种二进制打包格式,文件扩展名为 .whl。与传统的源代码包(如 .tar.gz)相比,Wheel 包无需编译,安装速度更快,特别适用于包含 C 扩展的包。

为什么选择 Wheel 包?

  • 快速安装:无需编译,直接安装二进制文件。
  • 兼容性好:支持多种 Python 版本和平台。
  • 标准化:已成为 Python 官方推荐的打包格式。

构建 Wheel 包

使用 setuptoolswheel 工具可以轻松构建 Wheel 包:

pip install setuptools wheel
python setup.py bdist_wheel

生成的 .whl 文件位于 dist/ 目录下。


3. pyproject.toml 文件

什么是 pyproject.toml

pyproject.toml 是 PEP 518 引入的配置文件标准,用于定义构建系统和项目的元数据。它旨在统一不同工具(如 Poetry、Flit、Black)的配置,并简化打包流程。

pyproject.toml 的基本结构

[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "your_package"
version = "0.1.0"
description = "A sample Python package"
authors = [
  { name="Your Name", email="your.email@example.com" }
]
dependencies = [
  "requests>=2.25.1",
  "numpy>=1.19.5"
]

pyproject.toml 的优势

  • 统一配置:一个文件管理所有配置,减少混乱。
  • 灵活性:支持多种构建后端,如 setuptoolsPoetry
  • 兼容性:符合 PEP 规范,未来支持更广泛的工具。

4. Poetry 简介

什么是 Poetry?

Poetry 是一个现代化的 Python 包管理工具,集依赖管理、打包和发布于一体。它基于 pyproject.toml,提供简洁的命令行界面,旨在简化和优化开发流程。

Poetry 的特点

  • 依赖管理:自动解析和锁定依赖,避免版本冲突。
  • 简化配置:使用 pyproject.toml 管理项目配置。
  • 集成打包:内置构建和发布功能,无需额外工具。
  • 虚拟环境管理:自动创建和管理项目的虚拟环境。

为什么选择 Poetry?

  • 易用性:简洁的命令和配置,降低学习曲线。
  • 可靠性:锁文件 (poetry.lock) 确保依赖的一致性。
  • 高效性:自动处理虚拟环境,优化开发体验。

5. 使用 Poetry 进行打包

本节将详细介绍如何使用 Poetry 从项目初始化到打包发布的全过程。

安装 Poetry

使用官方安装脚本

推荐使用官方提供的安装脚本:

curl -sSL https://install.python-poetry.org | python3 -

安装完成后,确保将 Poetry 添加到 PATH 中。通常安装路径为 $HOME/.local/bin

验证安装
poetry --version

输出示例:

Poetry version 1.4.0

初始化项目

在项目根目录下初始化一个新的 Poetry 项目:

poetry init

按照提示填写项目的名称、版本、描述、作者信息等。也可以使用 --no-interaction 参数跳过交互式提示,使用默认设置:

poetry init --no-interaction

管理依赖

添加依赖包

使用 poetry add 命令添加项目依赖:

poetry add requests

同时添加开发依赖:

poetry add --dev pytest
移除依赖包
poetry remove requests
更新依赖包
poetry update

配置 pyproject.toml

poetry init 命令会生成一个基本的 pyproject.toml 文件。可以根据需要手动编辑此文件。

示例 pyproject.toml
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "sample_package"
version = "0.1.0"
description = "A sample Python package using Poetry"
authors = ["Your Name <your.email@example.com>"]
license = "MIT"
readme = "README.md"
homepage = "https://github.com/yourusername/sample_package"
repository = "https://github.com/yourusername/sample_package"
documentation = "https://yourusername.github.io/sample_package/"

[tool.poetry.dependencies]
python = "^3.8"
requests = "^2.25.1"
numpy = "^1.19.5"

[tool.poetry.dev-dependencies]
pytest = "^6.2.4"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

构建 Wheel 包

使用以下命令构建 Wheel 包:

poetry build

构建成功后,dist/ 目录下会生成 .whl.tar.gz 文件。

发布到 PyPI

配置 PyPI 认证信息

使用以下命令配置 PyPI 账号信息:

poetry config pypi-token.pypi your_pypi_token

你可以在 PyPI 账户设置 创建一个新的 API token。

发布包

使用以下命令将包发布到 PyPI:

poetry publish --build

如果配置了 API token,可以直接发布。如果需要输入用户名和密码,可以省略 --build 参数:

poetry publish

发布成功后,其他用户可以通过 pip install your_package 安装你的包。


6. 示例项目实战:使用 Poetry 打包

通过一个完整的示例项目,演示如何使用 Poetry 进行打包和发布。

项目结构

sample_package/
│
├── sample_package/
│   ├── __init__.py
│   └── math_utils.py
│
├── tests/
│   └── test_math_utils.py
│
├── pyproject.toml
├── README.md
├── LICENSE
└── .gitignore

步骤详解

1. 创建项目目录
mkdir sample_package
cd sample_package
2. 初始化 Poetry 项目
poetry init --no-interaction
3. 添加依赖
poetry add requests
poetry add --dev pytest
4. 创建包目录和模块
mkdir sample_package
touch sample_package/__init__.py

sample_package/math_utils.py

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

sample_package/*init*.py

from .math_utils import add, subtract
5. 编写测试代码

tests/test_math_utils.py

import pytest
from sample_package import add, subtract

def test_add():
    assert add(2, 3) == 5

def test_subtract():
    assert subtract(5, 3) == 2
6. 配置 pyproject.toml

编辑 pyproject.toml,确保内容如下:

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "sample_package"
version = "0.1.0"
description = "A sample Python package using Poetry"
authors = ["Your Name <your.email@example.com>"]
license = "MIT"
readme = "README.md"
homepage = "https://github.com/yourusername/sample_package"
repository = "https://github.com/yourusername/sample_package"
documentation = "https://yourusername.github.io/sample_package/"

[tool.poetry.dependencies]
python = "^3.8"
requests = "^2.25.1"

[tool.poetry.dev-dependencies]
pytest = "^6.2.4"
7. 编写 README.md

README.md

# Sample Package

这是一个使用 Poetry 打包的示例 Python 包,用于演示现代化的包管理和发布流程。
8. 编写 LICENSE

选择合适的许可证,例如 MIT 许可证。

LICENSE

MIT License

...

(完整的 MIT 许可证文本)
9. 配置 .gitignore

.gitignore

__pycache__/
*.pyc
venv/
.env
dist/
build/
*.egg-info/
10. 安装依赖并运行测试

创建和激活虚拟环境:

poetry shell

安装依赖:

poetry install

运行测试:

pytest

所有测试应通过。

11. 构建包
poetry build

生成的 .whl.tar.gz 文件位于 dist/ 目录下。

12. 发布到 PyPI

确保已经配置了 PyPI 认证信息。

poetry publish --build

发布成功后,其他用户可以通过 pip install sample_package 安装该包。


7. 与 setuptools 的对比

setuptools 与 Poetry 的主要区别

特性setuptoolsPoetry
配置文件setup.py, setup.cfgpyproject.toml
依赖管理手动维护 requirements.txt, install_requires自动管理依赖,生成 poetry.lock
虚拟环境管理需手动创建和管理自动创建和管理虚拟环境
命令行接口分散的命令(如 python setup.py install集中统一的命令(如 poetry add, poetry publish
锁文件无官方支持支持 poetry.lock,确保依赖一致性
发布流程需要 twine 等工具辅助内置发布功能,简化流程
配置简洁性配置较为分散和复杂配置集中在 pyproject.toml,更简洁明了

选择建议

  • 新项目:推荐使用 Poetry,因其集成性和现代化特性更符合当前开发需求。
  • 现有项目:如果已有较为复杂的 setuptools 配置,迁移到 Poetry 需评估成本和收益。

8. 最佳实践与建议

1. 使用锁文件确保依赖一致性

锁文件 (poetry.lock) 记录了确切的依赖版本,确保在不同环境中安装的一致性。始终将锁文件提交到版本控制系统。

2. 遵循语义化版本控制

使用 MAJOR.MINOR.PATCH 格式管理版本号,明确标识 API 变更、功能新增和 bug 修复。

3. 编写详细的 README.md

提供项目的介绍、安装方法、使用示例和贡献指南,帮助用户快速上手。

4. 添加测试覆盖

使用 pytest 等工具编写测试,确保代码质量和功能正确性。

5. 使用持续集成(CI)

配置 CI 工具(如 GitHub Actions、Travis CI),自动运行测试、构建和发布,提升开发效率和可靠性。

6. 遵循 PEP 8 代码规范

保持代码风格一致,提高代码可读性和维护性。

7. 管理敏感信息

避免将敏感信息(如 API 密钥)硬编码到代码中,使用环境变量或配置文件管理。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值