Python 项目打包

  一、Python 项目打包

概念说明
PyPIPython 包索引,官方仓库(pypi.org
分发格式源码分发包(.tar.gz)和 Wheel 包(.whl
setup.py / pyproject.toml项目的配置文件,描述元数据和依赖
pip install从 PyPI 或本地安装包

二、项目结构

my_package/
├── src/                      # 源码目录
│   └── my_package/           # 包目录
│       ├── __init__.py
│       ├── module_a.py
│       └── module_b.py
├── pyproject.toml            # 项目配置(推荐)
├── setup.py                  # 传统配置文件
├── README.md
├── LICENSE
└── requirements.txt

三、配置 pyproject.toml

pyproject.toml 示例

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

[project]
name = "my_package"
version = "0.1.0"
description = "一个示例Python包"
readme = "README.md"
license = {text = "MIT"}
authors = [
    {name = "张三", email = "zhangsan@example.com"}
]
maintainers = [
    {name = "李四", email = "lisi@example.com"}
]
requires-python = ">=3.8"
classifiers = [
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.8",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]
keywords = ["example", "demo"]
dependencies = [
    "requests>=2.28.0",
    "numpy>=1.24.0",
    "pandas>=1.5.0",
]
optional-dependencies = {
    dev = [
        "pytest>=7.0.0",
        "black>=23.0.0",
        "ruff>=0.0.260",
    ],
    test = [
        "pytest>=7.0.0",
        "pytest-cov>=4.0.0",
    ]
}

[project.urls]
homepage = "https://github.com/zhangsan/my_package"
repository = "https://github.com/zhangsan/my_package.git"
documentation = "https://my_package.readthedocs.io"

[project.scripts]
my-cli = "my_package.__main__:main"

[project.gui-scripts]
my-gui = "my_package.gui:main"

[tool.setuptools]
package-dir = {"" = "src"}
packages = ["my_package"]

[tool.setuptools.package-data]
my_package = ["*.txt", "*.json", "data/*"]

pyproject.toml 核心字段

字段说明必需
[project]项目元数据必需
name包名(唯一标识,只能包含字母、数字、_、-)必需
version版本号(遵循 PEP 440)必需
description简短描述必需
dependencies运行时依赖
requires-pythonPython 版本要求
[project.scripts]命令行入口点

四、使用 setup.py(传统方式)

# setup.py
from setuptools import setup, find_packages

setup(
    name="my_package",
    version="0.1.0",
    author="张三",
    author_email="zhangsan@example.com",
    description="一个示例Python包",
    long_description=open("README.md", encoding="utf-8").read(),
    long_description_content_type="text/markdown",
    url="https://github.com/zhangsan/my_package",
    packages=find_packages("src"),
    package_dir={"": "src"},
    package_data={
        "my_package": ["*.txt", "*.json", "data/*"],
    },
    install_requires=[
        "requests>=2.28.0",
        "numpy>=1.24.0",
    ],
    extras_require={
        "dev": ["pytest>=7.0.0", "black>=23.0.0"],
        "test": ["pytest>=7.0.0", "pytest-cov>=4.0.0"],
    },
    entry_points={
        "console_scripts": [
            "my-cli=my_package.__main__:main",
        ],
        "gui_scripts": [
            "my-gui=my_package.gui:main",
        ],
    },
    classifiers=[
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.8",
        "Programming Language :: Python :: 3.9",
        "Programming Language :: Python :: 3.10",
        "License :: OSI Approved :: MIT License",
    ],
    python_requires=">=3.8",
)

setup.py vs pyproject.toml

特性setup.pypyproject.toml
语法Python 代码TOML 配置
可读性一般
动态配置支持有限支持
推荐度传统现代推荐

五、安装和打包命令

1. 本地开发安装(可编辑模式)

# 在项目根目录下
pip install -e .

# 安装额外依赖
pip install -e .[dev,test]

# 使用 uv(更快)
uv pip install -e .

2. 构建包

# 安装构建工具
pip install build

# 构建分发包
python -m build

# 生成文件
# dist/
#   my_package-0.1.0-py3-none-any.whl   # Wheel 包
#   my_package-0.1.0.tar.gz             # 源码包

# 使用 uv 构建
uv build

3. 本地安装包

# 安装 Wheel 包
pip install dist/my_package-0.1.0-py3-none-any.whl

# 安装源码包
pip install dist/my_package-0.1.0.tar.gz

4. 发布到 PyPI

# 安装 twine
pip install twine

# 上传到 PyPI(测试环境)
twine upload --repository testpypi dist/*

# 上传到 PyPI(正式环境)
twine upload dist/*

# 使用 uv 发布
uv publish

六、版本管理

版本号规范(PEP 440)

主版本号.次版本号.补丁版本号[-预发布标签]

示例:
1.0.0        # 正式版
1.0.0-alpha  # Alpha 版本
1.0.0-beta   # Beta 版本
1.0.0-rc1    # 候选版本

版本号约束

语法说明示例
==1.0.0精确版本requests==2.31.0
>=1.0.0大于或等于numpy>=1.24.0
>=1.0.0,<2.0.0版本范围pandas>=1.5.0,<2.0.0
~=1.0.0兼容版本(>=1.0.0,<1.1.0)flask~=2.3.0
*通配符django==4.*

七、入口点和命令行工具

创建命令行工具

# src/my_package/__main__.py
def main():
    print("这是 my-package 的命令行工具")
    import sys
    sys.exit(0)

if __name__ == "__main__":
    main()

配置入口点

# pyproject.toml
[project.scripts]
my-cli = "my_package.__main__:main"

安装后可以直接运行:

my-cli

八、依赖管理

声明依赖

# pyproject.toml
dependencies = [
    "requests>=2.28.0",
    "numpy>=1.24.0",
    "pandas>=1.5.0",
]

optional-dependencies = {
    dev = ["pytest>=7.0.0", "black>=23.0.0"],
    test = ["pytest>=7.0.0", "pytest-cov>=4.0.0"],
}

使用 requirements.txt

# requirements.txt
requests>=2.28.0
numpy>=1.24.0
pandas>=1.5.0
pip install -r requirements.txt

九、完整示例

项目结构

example_package/
├── src/
│   └── example_package/
│       ├── __init__.py
│       ├── core.py
│       └── __main__.py
├── tests/
│   ├── __init__.py
│   └── test_core.py
├── pyproject.toml
├── README.md
├── LICENSE
└── .gitignore

打包并发布

# 1. 清理旧构建文件
rm -rf dist/ build/ *.egg-info

# 2. 构建包
python -m build

# 3. 检查包
twine check dist/*

# 4. 上传到测试 PyPI
twine upload --repository testpypi dist/*

# 5. 从测试 PyPI 安装
pip install --index-url https://test.pypi.org/simple/ example-package

# 6. 上传到正式 PyPI
twine upload dist/*

十、常用工具

工具用途特点
pip安装包最常用
uv安装包(替代 pip)速度极快,兼容 pip
build构建包标准构建工具
twine上传包安全上传到 PyPI
setuptools打包配置传统工具
poetry项目管理一体化依赖管理
hatch项目管理现代 Python 项目管理工具
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值