setup.py 文件
python setup.py 命令的核心是一个名为 setup.py 的 Python 脚本,这个脚本定义了你的 Python 包的所有元数据和构建配置,当你在终端运行 python setup.py <command> 时,你实际上是在调用 Python 的 setuptools 库来执行指定的命令。
setuptools 是 Python 打包的事实标准,它极大地简化了创建、分发和安装 Python 包的过程。
setup.py 的基本结构
一个典型的 setup.py 文件长这样:
from setuptools import setup, find_packages
# 项目元数据
setup(
# 1. 基本信息
name="my-awesome-package", # 包名,在 PyPI 上必须是唯一的
version="0.1.0", # 版本号,遵循语义化版本规范
author="Your Name", # 作者
author_email="your.email@example.com", # 作者邮箱
description="A short description of my package.", # 简短描述
long_description="A more detailed description of my package...", # 详细描述(通常从 README.md 读取)
long_description_content_type="text/markdown", # 详细描述的格式,通常是 markdown
# 2. 包信息
packages=find_packages(), # 自动查找当前目录下的所有包
python_requires=">=3.6", # 支持的最低 Python 版本
# 3. 依赖信息
install_requires=[ # 运行此包所依赖的其他包
"requests >= 2.20.0",
"numpy",
],
extras_require={ # 可选依赖,通过 `pip install package[extra]` 安装
"dev": ["pytest", "black"],
"docs": ["sphinx"],
},
# 4. 其他配置
classifiers=[ # 用于在 PyPI 上分类你的项目,方便搜索
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
],
keywords="python, example, library", # 关键词
url="https://github.com/yourusername/my-awesome-package", # 项目主页
project_urls={ # 其他项目链接
"Bug Tracker": "https://github.com/yourusername/my-awesome-package/issues",
"Source Code": "https://github.com/yourusername/my-awesome-package",
},
)
常用的 python setup.py 命令
以下是你在开发过程中最常会用到的命令。
python setup.py sdist (创建源码分发包)
这个命令会创建一个源码发行版,它会将你的项目代码、setup.py 文件、README、LICENSE 等所有必要文件打包成一个 .tar.gz 文件。
- 作用:提供一个纯净的、未编译的源码包,适用于需要从源码编译安装的环境(例如某些 Linux 发行版)或希望查看源码的用户。
- 生成的文件:在
dist/目录下,my-awesome-package-0.1.0.tar.gz。
python setup.py bdist_wheel (创建 Wheel 分发包)
这是强烈推荐的打包方式,Wheel 是一种预编译的分发包格式,安装速度远快于源码包。
- 作用:为当前平台和 Python 版本创建一个
.whl文件。pip优先安装 Wheel 包。 - 生成的文件:在
dist/目录下,my_awesome_package-0.1.0-py3-none-any.whl。py3-none-any表示这个包不包含任何 C 扩展,可以用于任何 Python 3 环境。
python setup.py install (安装包)
这个命令会将你的包安装到当前 Python 环境中。
- 作用:在开发阶段测试你的包,它会将包文件复制到 Python 的
site-packages目录下。 - 注意:
- 这是一个“开发式安装”(development install),如果你修改了源码,已安装的包也会立即更新,无需重新运行
install。 - 对于最终用户,推荐使用
pip install .,因为它更现代化,能更好地处理依赖关系。
- 这是一个“开发式安装”(development install),如果你修改了源码,已安装的包也会立即更新,无需重新运行
python setup.py build (构建包)
这个命令是 sdist 和 bdist_wheel 的前置步骤,它会根据 setup.py 的配置编译所有代码(C 扩展)。
- 作用:通常你不需要手动运行它,
sdist和bdist_wheel会自动调用它,但如果你有复杂的编译需求,可以单独运行。
python setup.py --help-commands (查看所有可用命令)
如果你想了解 setuptools 支持的所有命令,可以使用这个。
现代实践:pyproject.toml 的崛起
近年来,Python 社区正在从 setup.py 向 pyproject.toml 标准过渡。pyproject.toml 是一个 TOML 格式的配置文件,它更清晰、更标准化,并且能更好地管理构建系统本身。
虽然 setup.py 仍然非常普遍,但新项目应该优先考虑 pyproject.toml。
pyproject.toml 示例
# pyproject.toml
[build-system]
requires = ["setuptools>=45", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "my-awesome-package"
version = "0.1.0"
description = "A short description of my package."
readme = "README.md"
requires-python = ">=3.6"
license = {text = "MIT"}
authors = [
{name = "Your Name", email = "your.email@example.com"},
]
dependencies = [
"requests >= 2.20.0",
"numpy",
]
keywords = ["python", "example", "library"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
]
[project.urls]
Homepage = "https://github.com/yourusername/my-awesome-package"
Repository = "https://github.com/yourusername/my-awesome-package"
"Bug Tracker" = "https://github.com/yourusername/my-awesome-package/issues"
[project.optional-dependencies]
dev = ["pytest", "black"]
docs = ["sphinx"]
使用 pyproject.toml 后,你的项目结构会是这样:
my-project/
├── src/
│ └── my_package/
│ └── __init__.py
├── pyproject.toml
└── README.md
打包命令也变得更简单:
# 创建 Wheel 分发包 pip wheel . # 创建源码分发包 python -m build --sdist # 安装包 pip install .
总结与最佳实践
| 命令 | 作用 | 备注 |
|---|---|---|
python setup.py sdist |
创建源码包 (.tar.gz) |
通用性最好,但安装慢。 |
python setup.py bdist_wheel |
创建 Wheel 包 (.whl) |
推荐,安装速度快,是现代标准。 |
python setup.py install |
开发时安装包 | 开发阶段方便,但推荐用 pip install .。 |
pip install . |
安装当前目录的包 | 现代推荐,能处理依赖和路径问题。 |
pip wheel . |
创建当前目录的 Wheel 包 | 现代推荐,比 bdist_wheel 更简洁。 |
python -m build |
构建分发包 (支持 sdist 和 wheel) | 未来标准,同时支持 setup.py 和 pyproject.toml。 |
最佳实践建议:
- 对于新项目:优先使用
pyproject.toml和src布局,使用pip和build模块进行打包和安装。 - 对于现有项目:如果项目还在使用
setup.py,完全可以继续使用它。python setup.py bdist_wheel和python setup.py sdist仍然是可靠且广泛使用的命令。 - 安装时:始终优先使用
pip install .而不是python setup.py install。 - 发布到 PyPI:在发布前,务必同时创建
sdist和wheel包,以确保最大的兼容性,可以使用python -m build一次性生成两者。
