Python项目打包教程:快速发布你的代码
知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个文章开发实战,手把手教大家学习《Python项目打包指南:轻松发布你的代码》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!
在Python中打包自己的项目,最核心的思路是利用Python的包管理生态,尤其是setuptools
这个工具链,来将你的代码、元数据和依赖项封装成一个可分发的格式,通常是.whl
(wheel)或.tar.gz
(source distribution)。这使得其他人,或者你自己在不同环境中,都能方便地安装和使用你的代码。
解决方案
要打包一个Python项目,现代且推荐的做法是围绕pyproject.toml
文件进行配置,这让整个过程更加标准化和清晰。当然,如果你在维护一个老项目,可能还会遇到setup.py
。但我们这里主要聊聊pyproject.toml
。
首先,你需要一个合理的项目结构。我个人比较偏爱src
布局,即把所有实际的Python代码放在一个名为src
的子目录里,这样做的好处是能更好地模拟安装后的环境,避免一些常见的导入问题。比如:
my_project/ ├── src/ │ └── my_package/ │ ├── __init__.py │ └── main.py ├── pyproject.toml ├── README.md └── LICENSE
接下来,关键是创建pyproject.toml
文件。这个文件定义了你的项目如何被构建以及它的元数据。一个基本的pyproject.toml
可能看起来像这样:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "my-awesome-package" version = "0.1.0" authors = [ { name="Your Name", email="your.email@example.com" }, ] description = "一个关于我的Python项目的简短描述。" readme = "README.md" requires-python = ">=3.8" classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ] dependencies = [ "requests>=2.28.1", "rich~=13.0", ] [project.urls] "Homepage" = "https://github.com/yourusername/my-awesome-package" "Bug Tracker" = "https://github.com/yourusername/my-awesome-package/issues" [tool.setuptools.packages.find] where = ["src"] # 告诉setuptools去src目录找包
这里面,[build-system]
部分告诉构建工具应该用什么来构建你的项目,通常是setuptools
。[project]
部分则包含了项目的核心元数据:名称、版本、作者、描述、依赖等等。dependencies
字段非常重要,它列出了你的项目运行时所依赖的其他Python包。[tool.setuptools.packages.find]
则是我在src
布局下,告诉setuptools
去哪里寻找我的Python包。
如果你有一些非Python文件需要包含在包里(比如配置文件、数据文件),setuptools
会默认包含在src
目录下的非Python文件。如果文件在其他地方,或者你需要更细致的控制,可能需要一个MANIFEST.in
文件,但对于大多数项目,pyproject.toml
的默认行为已经够用了。
配置好这些后,打包就非常简单了。确保你安装了build
工具:pip install build
。然后,在你的项目根目录(pyproject.toml
所在的目录)运行:
python -m build
这个命令会在你的项目根目录下创建一个dist/
目录,里面就会有你的.whl
和.tar.gz
文件。.whl
是预编译的二进制分发包,安装更快;.tar.gz
是源代码分发包,包含所有源代码和元数据。
打包过程本身并不复杂,真正的挑战往往在于如何合理组织代码、管理依赖,以及处理一些边缘情况,比如包含非Python资源。但只要遵循pyproject.toml
的规范,大部分问题都能迎刃而解。
Python项目打包时,有哪些主流工具可以选择?它们之间有什么区别?
在Python的世界里,打包工具的选择其实还挺丰富的,但它们各有侧重,理解这些差异能帮助你根据项目需求做出最佳选择。
1. setuptools
(搭配 pyproject.toml
或 setup.py
)
- 特点: 毫无疑问,它是Python生态的基石,几乎所有其他工具最终都可能依赖它来完成实际的构建工作。它提供了非常细致的控制能力,可以处理各种复杂的打包场景,比如C扩展、数据文件等。
- 优点: 极度灵活,功能强大,社区支持广泛,兼容性最好。通过
pyproject.toml
配置,现代项目也能保持简洁。 - 缺点: 配置起来相对复杂,尤其是当你需要处理一些非标准情况时。早期的
setup.py
脚本模式容易导致代码和配置混淆。 - 我的看法: 对于需要最大兼容性、或者包含C扩展的库,
setuptools
依然是首选。它就像一把瑞士军刀,虽然有些功能不常用,但关键时刻总能派上用场。现在有了pyproject.toml
,它的配置体验也大大改善了。
2. Poetry
- 特点:
Poetry
不仅仅是一个打包工具,它更是一个完整的Python项目管理工具,集成了依赖管理、虚拟环境管理和打包发布。它非常注重确定性和易用性。 - 优点: 极大地简化了依赖管理和虚拟环境操作。它使用
pyproject.toml
来定义所有内容,包括依赖锁定(poetry.lock
),确保每次安装都得到相同的依赖版本。打包和发布命令也非常直观。 - 缺点: 它的“全能”有时也意味着它的“固执”。如果你已经有了一套成熟的依赖管理流程,或者不喜欢它的某些默认行为,可能会觉得它有些限制。
- 我的看法: 对于新的应用程序项目,尤其是那些需要严格依赖锁定的项目,
Poetry
是个非常棒的选择。它能让你的开发体验变得丝滑,减少很多因依赖冲突带来的头疼。但对于纯粹的库项目,我可能会考虑更轻量级的方案,或者依然用setuptools
。
3. Flit
- 特点:
Flit
专注于纯Python模块的打包,目标是提供一个极其简单、零配置的打包体验。它也使用pyproject.toml
。 - 优点: 配置简单到令人发指,对于纯Python库,你只需要在
pyproject.toml
里写几行元数据,Flit
就能帮你完成打包。它强制使用src
布局,这本身也是一个好实践。 - 缺点: 只能打包纯Python模块,不支持C扩展或其他复杂资源。
- 我的看法: 如果你的项目是一个纯Python的库,没有C扩展,也不需要特别复杂的打包逻辑,
Flit
绝对值得一试。它的简洁性会让你爱不释手。
4. Hatch
- 特点:
Hatch
是一个相对较新的项目管理工具,目标是成为Python项目的“一站式”解决方案,涵盖了虚拟环境、脚本运行、测试、打包和发布。它也基于pyproject.toml
。 - 优点: 提供了非常全面的功能,并且设计上考虑了扩展性,允许用户自定义各种插件。它的配置比
Poetry
更灵活,但又比setuptools
更集成。 - 缺点: 作为一个较新的工具,社区成熟度可能不如
setuptools
或Poetry
。功能丰富也意味着学习曲线可能稍长。 - 我的看法:
Hatch
是一个很有潜力的工具,它试图在Poetry
的集成性和setuptools
的灵活性之间找到一个平衡点。如果你正在寻找一个现代、功能全面且可定制的项目管理工具,Hatch
是一个值得关注的选项。
选择哪个工具,很大程度上取决于你的项目类型、团队偏好以及你对工具集成度的要求。对我而言,如果是纯库,setuptools
with pyproject.toml
提供足够的灵活性;如果是应用程序,Poetry
的依赖管理优势很明显。
在Python项目中,如何有效地管理项目依赖和版本控制?
依赖管理和版本控制是项目健康运行的关键。我见过太多项目因为依赖问题而陷入泥潭,所以这块的处理,我觉得怎么强调都不过分。
1. 依赖声明:pyproject.toml
的dependencies
这是现代Python项目声明直接依赖的首选方式。在pyproject.toml
的[project]
部分,你可以列出项目运行所需的所有包及其版本要求。
[project] dependencies = [ "requests>=2.28.1,<3.0", # 明确版本范围 "numpy~=1.23.0", # 兼容版本,例如 1.23.x "pandas", # 不指定版本,但通常不推荐在库中使用 ]
- 版本指定策略:
==1.2.3
: 精确版本,确保每次都安装特定版本。适用于应用程序,追求确定性。>=1.2.3
: 最低版本要求。适用于库,允许用户使用更新的版本。~=1.2.3
(或~1.2.3
): 兼容版本,例如~=1.2.3
意味着>=1.2.3
且<1.3.0
。这是一个很好的折衷方案,允许小版本更新,同时避免引入大的不兼容变更。>=1.2.3,<2.0.0
: 显式指定一个版本范围,通常用于兼容某个大版本系列。 我个人倾向于在库项目中多用~=
或>=X.Y.Z,
,而在应用程序中,会更倾向于精确锁定或由 Poetry
、pip-tools
等工具生成锁文件。
2. 依赖锁定:poetry.lock
或 requirements.txt
仅仅声明依赖是不够的,你还需要锁定它们及其所有传递性依赖的具体版本。这确保了在不同时间、不同机器上安装项目时,都能得到完全相同的依赖环境,避免“在我机器上没问题”的尴尬。
Poetry
的poetry.lock
: 如果你使用Poetry
,它会自动为你生成一个poetry.lock
文件。这个文件包含了所有直接和间接依赖的精确版本和哈希值,确保了高度的确定性。pip-tools
生成的requirements.txt
: 如果你不使用Poetry
,但仍希望锁定依赖,pip-tools
是一个非常棒的工具。你可以在requirements.in
中声明你的直接依赖,然后用pip-compile
命令生成一个详细的requirements.txt
文件,里面包含了所有依赖的精确版本。# requirements.in requests rich # 生成 requirements.txt pip-compile requirements.in
然后安装时使用
pip install -r requirements.txt
。
3. 虚拟环境(Virtual Environments):
这是Python依赖管理的基础。永远不要在全局Python环境中安装项目依赖。使用venv
、conda
或Poetry
自带的虚拟环境,为每个项目创建一个隔离的Python环境。这可以防止不同项目之间的依赖冲突。
# 使用 venv python -m venv .venv source .venv/bin/activate # Linux/macOS .venv\Scripts\activate # Windows pip install -r requirements.txt
4. 版本控制(Semantic Versioning - SemVer):
为你的项目本身以及你所依赖的第三方库选择合理的版本控制策略,尤其是语义化版本(MAJOR.MINOR.PATCH
)非常重要。
MAJOR
版本:不兼容的API变更。MINOR
版本:向下兼容的新功能。PATCH
版本:向下兼容的bug修复。 遵循SemVer能让你的用户更好地理解你的版本更新意味着什么,并帮助他们在升级时做出明智的决策。
5. 挑战与实践:
- 依赖冲突: 当你的项目依赖的两个库又分别依赖同一个第三方库的不同版本时,就可能出现冲突。这时,你需要权衡,看能否升级其中一个依赖,或者寻找替代方案。锁文件(
poetry.lock
或requirements.txt
)能帮助你及早发现这些冲突。 - 环境隔离: 始终强调虚拟环境的重要性。它能让你在本地开发时避免“依赖地狱”。
- 自动化: 将依赖管理集成到CI/CD流程中,例如,在每次构建时都检查依赖是否最新,或者自动更新锁文件。
对我来说,依赖管理是一个持续的过程。它不是一次性的配置,而是随着项目演进需要不断审视和调整的。使用合适的工具和策略,可以大大减少这方面的摩擦。
如何将我的Python包发布到PyPI或一个私有仓库?
将你的Python包发布出去,无论是公开的PyPI还是私有的仓库,都是为了让其他人(或你自己)能够方便地安装和使用它。这个过程通常涉及构建、认证和上传三个主要步骤。
1. 发布到PyPI(Python Package Index)
PyPI是Python官方的公共包索引,是大多数开源Python包的首选发布平台。
a. 准备工作:
- 注册PyPI账户: 如果你还没有,需要在 PyPI官网 注册一个账户。同时,为了安全起见,强烈建议开启双重认证(2FA)。
- 创建API Token: 不要使用你的PyPI用户名和密码直接上传。在PyPI账户设置中生成一个API Token,并为其分配一个适当的权限(例如,仅允许上传到你的特定项目)。将这个Token保存好,因为它只会显示一次。
- 安装
twine
:twine
是一个安全的包上传工具,它能确保你的包在上传过程中加密。pip install twine
b. 构建你的包:
确保你已经按照前面的“解决方案”部分,使用python -m build
命令构建了你的包。这会在dist/
目录下生成.whl
和.tar.gz
文件。
c. 上传包:
使用twine
将dist/
目录下的所有包文件上传到PyPI。
twine upload dist/*
运行这个命令后,twine
会提示你输入用户名和密码。
- 用户名: 输入
__token__
(注意是两个下划线)。 - 密码: 输入你之前生成的API Token。
如果一切顺利,你的包就会被上传到PyPI,并且你可以在PyPI网站上看到它。之后,任何人都可以通过pip install your-awesome-package
来安装你的包了。
2. 发布到私有仓库
有时,你的包不适合公开,或者你希望在企业内部共享。这时,私有仓库就派上用场了。常见的私有仓库解决方案有:
- Artifactory (JFrog Artifactory)
- Nexus Repository Manager (Sonatype Nexus)
- GitLab Package Registry
- GitHub Packages
- devpi (一个轻量级的PyPI兼容服务器)
a. 配置私有仓库: 这通常涉及到在你的私有仓库服务中创建一个新的Python仓库,并获取其URL和认证凭据(API Key, 用户名/密码等)。
b. 构建你的包:
与发布到PyPI一样,先用python -m build
构建你的包。
c. 上传包:
你仍然可以使用twine
来上传,但需要指定私有仓库的URL。
twine upload --repository-url https://your-private-repo.com/pypi/your-repo/ dist/*
twine
会提示你输入私有仓库的用户名和密码。具体认证方式取决于你的私有仓库配置,可能是一个API Key,也可能是普通的用户名和密码。
d. 从私有仓库安装:
一旦包上传成功,其他人就可以通过pip
从你的私有仓库安装它。
pip install --index-url https://your-private-repo.com/pypi/your-repo/ your-awesome-package
如果私有仓库需要认证,你可能还需要在URL中包含凭据,或者通过~/.pip/pip.conf
(或pip.ini
)文件进行配置:
# ~/.pip/pip.conf [global] index-url = https://username:password@your-private-repo.com/pypi/your-repo/
或者,为了安全,使用--extra-index-url
来指定私有仓库,同时保留PyPI作为主索引,这样可以安装私有包,也能安装公共包:
pip install --extra-index-url https://username:password@your-private-repo.com/pypi/your-repo/ your-awesome-package
安全提示:
永远不要将API Token或密码硬编码到脚本或版本控制中。使用环境变量、CI/CD工具的秘密管理功能,或者
~/.pypirc
文件来存储凭据。~/.pypirc
文件可以配置不同的仓库别名和认证信息,例如:[distutils] index-servers = pypi my-private-repo [pypi] username = __token__ password = pypi-api-token [my-private-repo] repository = https://your-private-repo.com/pypi/your-repo/ username = repo-username password = repo-password
然后你可以使用
twine upload --repository my-private-repo dist/*
。
发布包是项目生命周期中非常重要的一环,它将你的代码从本地环境推向更广阔的舞台。理解这些工具和流程,能让你更自信地管理和分发你的Python项目。
今天带大家了解了的相关知识,希望对你有所帮助;关于文章的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

- 上一篇
- 微信拍一拍怎么设置和使用

- 下一篇
- Python浮点数精度问题与解决方法
-
- 文章 · python教程 | 49分钟前 |
- Python多线程与多进程区别全解析
- 338浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- Python字符串反转的几种方法
- 410浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- Python字符串split()方法详解
- 322浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- Python中abs函数的作用与用法详解
- 115浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- Python浮点数精度问题与解决方法
- 219浏览 收藏
-
- 文章 · python教程 | 2小时前 | Python 文件重命名 os模块 os.rename() os.replace()
- Python轻松重命名文件教程
- 468浏览 收藏
-
- 文章 · python教程 | 3小时前 |
- PythonNumPy数组创建全解析
- 353浏览 收藏
-
- 文章 · python教程 | 3小时前 | 函数 日期格式化 日期解析 datetime模块 Python日期处理
- Python日期处理函数使用详解
- 337浏览 收藏
-
- 文章 · python教程 | 3小时前 |
- PyCharm界面功能全解析
- 376浏览 收藏
-
- 文章 · python教程 | 4小时前 |
- unittest与pytest单元测试详解
- 481浏览 收藏
-
- 文章 · python教程 | 5小时前 |
- Python多线程怎么用?详解实现方法
- 283浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 514次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 499次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- AI Mermaid流程图
- SEO AI Mermaid 流程图工具:基于 Mermaid 语法,AI 辅助,自然语言生成流程图,提升可视化创作效率,适用于开发者、产品经理、教育工作者。
- 661次使用
-
- 搜获客【笔记生成器】
- 搜获客笔记生成器,国内首个聚焦小红书医美垂类的AI文案工具。1500万爆款文案库,行业专属算法,助您高效创作合规、引流的医美笔记,提升运营效率,引爆小红书流量!
- 671次使用
-
- iTerms
- iTerms是一款专业的一站式法律AI工作台,提供AI合同审查、AI合同起草及AI法律问答服务。通过智能问答、深度思考与联网检索,助您高效检索法律法规与司法判例,告别传统模板,实现合同一键起草与在线编辑,大幅提升法律事务处理效率。
- 694次使用
-
- TokenPony
- TokenPony是讯盟科技旗下的AI大模型聚合API平台。通过统一接口接入DeepSeek、Kimi、Qwen等主流模型,支持1024K超长上下文,实现零配置、免部署、极速响应与高性价比的AI应用开发,助力专业用户轻松构建智能服务。
- 758次使用
-
- 迅捷AIPPT
- 迅捷AIPPT是一款高效AI智能PPT生成软件,一键智能生成精美演示文稿。内置海量专业模板、多样风格,支持自定义大纲,助您轻松制作高质量PPT,大幅节省时间。
- 648次使用
-
- Flask框架安装技巧:让你的开发更高效
- 2024-01-03 501浏览
-
- Django框架中的并发处理技巧
- 2024-01-22 501浏览
-
- 提升Python包下载速度的方法——正确配置pip的国内源
- 2024-01-17 501浏览
-
- Python与C++:哪个编程语言更适合初学者?
- 2024-03-25 501浏览
-
- 品牌建设技巧
- 2024-04-06 501浏览