python使用pip之setup.py编写

1. 基础结构

setup.py 是 Python 打包的核心配置文件,需使用 setuptools 库定义包的元数据和构建规则。

基本模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from setuptools import setup, find_packages

setup(
name="your-package-name", # 包名(PyPI唯一标识)
version="0.1.0", # 版本号
author="Your Name",
author_email="[email protected]",
description="Short description",
long_description=open("README.md").read(), # 长描述(README内容)
long_description_content_type="text/markdown", # README格式
url="https://github.com/yourusername/your-package", # 项目地址
packages=find_packages(), # 自动发现包目录
install_requires=[], # 依赖库列表
entry_points={}, # 命令行工具入口
classifiers=[], # PyPI分类标签
python_requires=">=3.6", # Python版本要求
)

2. 关键参数详解

(1) name

  • 作用:包在 PyPI 上的唯一标识符。
  • 规则
    • 必须全小写,可用连字符(-),如 my-package
    • 需在 PyPI 上未被占用(上传前检查)。

(2) version

  • 作用:包的版本号,每次更新必须递增。
  • 格式:推荐语义化版本(如 1.0.0, 0.2.5)。

(3) packages

  • 作用:指定包含的 Python 包目录。
  • 自动发现
    1
    packages=find_packages(),  # 自动搜索所有含 __init__.py 的目录
  • 手动指定
    1
    packages=["my_package", "my_package.submodule"],

(4) install_requires

  • 作用:定义包的依赖库及版本约束。
  • 示例
    1
    2
    3
    4
    5
    install_requires=[
    "requests>=2.25.1", # 最低版本
    "numpy<1.22,>=1.20", # 版本范围
    "pandas", # 不限制版本
    ]

(5) entry_points

  • 作用:定义命令行工具入口,生成可执行命令。
  • 示例
    1
    2
    3
    4
    5
    entry_points={
    "console_scripts": [
    "my-command=my_package.module:main", # 格式:命令名=包.模块:函数
    ],
    }
    • 用户安装后可直接运行 my-command

(6) package_data

  • 作用:包含包内的非代码文件(如数据、配置文件)。
  • 示例
    1
    2
    3
    package_data={
    "my_package": ["data/*.csv", "templates/*.html"],
    },

(7) include_package_data

  • 作用:自动包含 MANIFEST.in 中指定的文件。
  • 用法
    1
    include_package_data=True,  # 需配合 MANIFEST.in 文件

(8) classifiers

  • 作用:为 PyPI 提供包的分类标签(便于搜索)。
  • 常用选项
    1
    2
    3
    4
    5
    6
    classifiers=[
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
    "Topic :: Software Development :: Libraries",
    ]

3. 完整示例

假设项目结构如下:

1
2
3
4
5
6
7
8
9
my_project/
├── my_package/
│ ├── __init__.py
│ ├── main.py
│ └── data/
│ └── config.json
├── README.md
├── LICENSE
└── 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
from setuptools import setup, find_packages

setup(
name="my-awesome-tool",
version="0.1.0",
author="Jane Doe",
author_email="[email protected]",
description="A tool to do awesome things.",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
url="https://github.com/janedoe/my-awesome-tool",
packages=find_packages(),
install_requires=[
"requests>=2.25.1",
"click>=8.0.0", # 命令行库
],
entry_points={
"console_scripts": [
"awesome-tool=my_package.main:cli", # 假设 main.py 有 cli() 函数
],
},
package_data={
"my_package": ["data/*.json"], # 包含 data 目录下的 JSON 文件
},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires=">=3.7",
)


4. 包含额外文件:MANIFEST.in

如果需要包含包外的文件(如文档、测试数据),需创建 MANIFEST.in 文件:

1
2
3
include LICENSE README.md
recursive-include docs *
recursive-include tests *


5. 验证与打包

(1) 生成分发包

1
2
pip install setuptools wheel  # 确保工具已安装
python setup.py sdist bdist_wheel # 生成源码包和二进制包
  • 生成文件在 dist/ 目录。

(2) 本地测试安装

1
2
pip install .  # 在当前目录安装包
awesome-tool # 测试命令行工具

6. 关键注意事项

  1. 包名唯一性:在 PyPI 搜索确认包名未被占用。
  2. 版本号递增:每次更新代码后需修改 version
  3. 依赖管理:精确指定依赖版本,避免未来更新导致兼容性问题。
  4. 许可证:必须包含 LICENSE 文件,并在 classifiers 中声明。
  5. 入口函数:确保 entry_points 指向的函数已正确定义。

通过以上步骤,你可以编写一个完整的 setup.py 文件,为发布到 PyPI 做好准备。


7. 提一嘴之生成可执行文件

使用工具如 PyInstaller 或 cx_Freeze 将Python脚本转换为独立的可执行文件:

1. 使用 PyInstaller

  • 安装
1
pip install pyinstaller
  • 生成可执行文件
1
pyinstaller --onefile your_script.py
  • --onefile 生成单个可执行文件。

  • 输出在 dist/ 目录中。

  • 跨平台:需在目标操作系统下分别打包。

2. 注意事项

  • 依赖处理:PyInstaller会自动分析脚本依赖,但某些复杂情况(如动态导入)可能需要手动配置(使用 .spec 文件)。

  • 文件大小:因包含Python解释器和依赖库,生成文件较大。


python使用pip之setup.py编写
http://example.com/2025/02/04/python使用pip之setup-py编写/
作者
JunBin Liang
发布于
2025年2月4日
许可协议