Python程序包的构建和发布过程示例详解


Posted in Python onJune 09, 2019

关于我

编程界的一名小程序猿,目前在一个创业团队任team lead,技术栈涉及Android、Python、Java和Go,这个也是我们团队的主要技术栈。 联系:hylinux1024@gmail.com

当我们开发了一个开源项目时,就希望把这个项目打包然后发布到 pypi.org 上,别人就可以通过 pip install 的命令进行安装。本文的教程来自于 Python 官方文档 , 如有不正确的地方欢迎评论拍砖。

0x00 创建项目

本文使用到的项目目录为

➜ packaging-tutorial
.
└── bestpkg
  └── __init__.py

接下来的所有操作都是在 packing_tutorial 这个目录下进行的。首先把 bestpkg 这个目录下的 __init__.py 添加以下内容

info='packaging demo'

这个信息主要用于打包成功后安装测试用的。

0x01 项目结构

一个待发布的项目还需要有以下这些文件: setup.py 、 LICENSE 和 README.md

➜ packaging-tutorial
.
├── LICENSE
├── README.md
├── bestpkg
│  └── __init__.py
└── setup.py

0x02 setup.py

setup.py 文件是给 setuptools 工具的使用脚本,告诉 setuptools 如何构建我们的项目。打开编辑器,编辑 setup.py 文件,输入以下内容

import setuptools

# 读取项目的readme介绍
with open("README.md", "r") as fh:
  long_description = fh.read()

setuptools.setup(
  name="bestpkg",# 项目名称,保证它的唯一性,不要跟已存在的包名冲突即可
  version="0.0.1",
  author="hylinux1024", # 项目作者
  author_email="hylinux1024@gmail.com",
  description="一个牛逼的程序", # 项目的一句话描述
  long_description=long_description,
  long_description_content_type="text/markdown",
  url="https://github.com/hylinux1024/niubiproject",# 项目地址
  packages=setuptools.find_packages(),
  classifiers=[
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
  ],
)
  • name 
  • 项目名称,保证它的唯一性,不要跟已存在的包名冲突即可,否则会发布失败
  • version 
  • 版本号
  • author 
  • 作者
  • author_email 
  • 作者邮箱
  • description 
  • 一句话描述项目
  • long_description 
  • 项目详细说明,一般直接读取README.md的内容
  • url 
  • 项目的链接地址
  • packages 
  • 列出当前项目的包,一般直接使用 find_packages() 即可
  • classifiers 
  • 这里指定 Python 的兼容版本是 Python3 ,也指定了项目使用的开源协议。

0x03 README.md

给项目添加详细的 README

# Example Package

This is a simple example package. You can use
[Github-flavored Markdown](https://guides.github.com/features/mastering-markdown/)
to write your content.

0x04 LICENSE

要发布包到 pypi 上,选择一个合适的开源协议是非常重要的。如果不知道怎么选可以到choosealicense.com/这里看看。

0x05 项目打包

项目需要打包后才能发布,要打包项目需先安装最新版本的 setuptools 和 wheel

➜ python3 -m pip install --user --upgrade setuptools wheel

然后使用以下命令进行打包

➜ python3 setup.py sdist bdist_wheel

当看到以下信息,说明已经打包成功

...
...
...
adding license file "LICENSE" (matched pattern "LICEN[CS]E*")
creating build/bdist.macosx-10.14-x86_64/wheel/bestpkg-0.0.1.dist-info/WHEEL
creating 'dist/bestpkg-0.0.1-py3-none-any.whl' and adding 'build/bdist.macosx-10.14-x86_64/wheel' to it
adding 'bestpkg/__init__.py'
adding 'bestpkg-0.0.1.dist-info/LICENSE'
adding 'bestpkg-0.0.1.dist-info/METADATA'
adding 'bestpkg-0.0.1.dist-info/WHEEL'
adding 'bestpkg-0.0.1.dist-info/top_level.txt'
adding 'bestpkg-0.0.1.dist-info/RECORD'
removing build/bdist.macosx-10.14-x86_64/wheel

在项目目录下会生成一个 dist 和 build 文件夹

➜ packaging-tutorial tree
.
├── LICENSE
├── README.md
├── bestpkg
│  └── __init__.py
├── bestpkg.egg-info
│  ├── PKG-INFO
│  ├── SOURCES.txt
│  ├── dependency_links.txt
│  └── top_level.txt
├── build
│  ├── bdist.macosx-10.14-x86_64
│  ├── bdist.macosx-10.9-x86_64
│  └── lib
│    └── bestpkg
│      └── __init__.py
├── dist
│  ├── bestpkg-0.0.1-py3-none-any.whl
│  └── bestpkg-0.0.1.tar.gz
└── setup.py

8 directories, 11 files

在 dist 文件中有两个文件

dist
  ├── bestpkg-0.0.1-py3-none-any.whl
  └── bestpkg-0.0.1.tar.gz

tar.gz 文件是源码文件压缩包,而 .whl 就是打包后的文件。最新的 pip 命令会安装这个 .whl 文件。

0x06 上传

现在就可以上传到 Python 索引库了。我们使用 Test PyPI ,这个是测试用的 Pypi ,本例子也是使用 Test Pypi 。

首先要到 test.pypi.org/account/reg… 注册账号。本例中我注册的账号为: hylinux1024 。

然后使用 twine 工具来上传我们的包。使用以下命令进行安装:

➜ python3 -m pip install --user --upgrade twine

使用以下命令上传 dist 目录下的文件

➜ python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*

这个命令会提示输入刚在 test.pypi.org 上注册账号密码,并出现类似以下信息后说明已经上传成功。

Enter your username: hylinux1024
Enter your password:
Uploading distributions to https://test.pypi.org/legacy/
Uploading bestpkg-0.0.1-py3-none-any.whl
100%|??????????????????????????????????????| 4.57k/4.57k [00:00<00:00, 8.01kB/s]
Uploading bestpkg-0.0.1.tar.gz
100%|??????????????????????????????????????| 4.18k/4.18k [00:01<00:00, 3.23kB/s]

然后打开 test.pypi.org/project/bes… 这个地址就可以看到我们发布的包。

0x07 安装

发布成功之后就可以使用 pip 来安装来。我们在虚拟环境中安装,关于虚拟环境可以看我前一篇文章。

这里就使用 pipenv ,这里我直接进入到我昨天创建的那个项目中,也为了更好演示安装结果。

➜ pip install --index-url https://test.pypi.org/simple/ --no-deps bestpkg

在这里我使用 --index-url 参数是为了指定从 test.pypi.org 中安装,而不是正式包索引库中查找要安装的包。还有使用了 --no-deps 参数是因为本例中没有使用到其它的依赖库。

在终端会看到以下类似信息,说明安装成功

Looking in indexes: https://test.pypi.org/simple/
Collecting bestpkg
 Downloading https://test-files.pythonhosted.org/packages/5a/fc/c109b3872b6c06e7368c30b6e52501113846f90ca716a434766151093173/bestpkg-0.0.1-py3-none-any.whl
Installing collected packages: bestpkg
Successfully installed bestpkg-0.0.1

进入交互界面

(pipenvdemo) ➜ pipenvdemo python
>>> import bestpkg
>>> bestpkg.info
'packaging demo'

info 变量就是在 __init__.py 文件中定义的变量。自此我们的包发布、安装使用流程就走完了。

要在正式的 Python 索引库中发布,只需要到pypi.org/注册账号,并上传就可以了。

0x08 总结一下

通过一个简单的例子展示 Python 通过 setuptools 工具进行打包,然后上传到 test.pypi.org 的流程。如果要上传到正式的 pypi.org 上,只需要注册一个正式的账号。一旦发布成功就可以使用 pip install [your-package] 的命令进行安装。

总结

以上所述是小编给大家介绍的Python程序包的构建和发布过程示例详解,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Python 相关文章推荐
Python+Turtle动态绘制一棵树实例分享
Jan 16 Python
python使用tcp实现局域网内文件传输
Mar 20 Python
Python2和3字符编码的区别知识点整理
Aug 08 Python
pandas 缺失值与空值处理的实现方法
Oct 12 Python
DataFrame.to_excel多次写入不同Sheet的实例
Dec 02 Python
Python参数传递对象的引用原理解析
May 22 Python
Python turtle库的画笔控制说明
Jun 28 Python
Python requests模块安装及使用教程图解
Jun 30 Python
Python TestSuite生成测试报告过程解析
Jul 23 Python
python爬虫线程池案例详解(梨视频短视频爬取)
Feb 20 Python
Python绘制地图神器folium的新人入门指南
May 23 Python
解决Pytorch半精度浮点型网络训练的问题
May 24 Python
Python面向对象之继承和多态用法分析
Jun 08 #Python
Python基本数据结构之字典类型dict用法分析
Jun 08 #Python
Python学习笔记基本数据结构之序列类型list tuple range用法分析
Jun 08 #Python
Python面向对象之类的封装操作示例
Jun 08 #Python
Python面向对象之类和实例用法分析
Jun 08 #Python
Python学习笔记之自定义函数用法详解
Jun 08 #Python
Python3基础教程之递归函数简单示例
Jun 07 #Python
You might like
Thinkphp微信公众号支付接口
2016/08/04 PHP
PHPstorm快捷键(分享)
2017/07/17 PHP
浅谈Laravel队列实现原理解决问题记录
2017/08/19 PHP
如何在Web页面上直接打开、编辑、创建Office文档
2007/03/12 Javascript
深入理解JavaScript系列(15) 函数(Functions)
2012/04/12 Javascript
jquery 检测元素是否存在的实例代码
2013/11/19 Javascript
jQuery Validation PlugIn的使用方法详解
2015/12/18 Javascript
js实现div在页面拖动效果
2016/05/04 Javascript
JQuery学习总结【一】
2016/12/01 Javascript
jquery插入兄弟节点的操作方法
2016/12/07 Javascript
完美解决JS文件页面加载时的阻塞问题
2016/12/18 Javascript
js编写简单的聊天室功能
2017/08/17 Javascript
AngularJS实现图片上传和预览功能的方法分析
2017/11/08 Javascript
js中el表达式的使用和非空判断方法
2018/03/28 Javascript
详解Require.js与Sea.js的区别
2018/08/05 Javascript
关于vue组件事件属性穿透详解
2019/10/28 Javascript
vue elementUI 表单校验的实现代码(多层嵌套)
2019/11/06 Javascript
webpack优化之代码分割与公共代码提取详解
2019/11/22 Javascript
JavaScript indexOf()原理及使用方法详解
2020/07/09 Javascript
利用Python实现简单的相似图片搜索的教程
2015/04/23 Python
Python实现把数字转换成中文
2015/06/29 Python
python使用标准库根据进程名如何获取进程的pid详解
2017/10/31 Python
python多进程 主进程和子进程间共享和不共享全局变量实例
2020/04/25 Python
Django使用Profile扩展User模块方式
2020/05/14 Python
使用CSS3 制作一个material-design 风格登录界面实例
2016/12/12 HTML / CSS
css3 transform导致子元素固定定位变成绝对定位的方法
2020/03/06 HTML / CSS
HTML5边玩边学(1)画布实现方法
2010/09/21 HTML / CSS
Html5与App的通讯方式详解
2019/10/24 HTML / CSS
Unix如何在一行中运行多个命令
2015/05/29 面试题
开学寄语大全
2014/04/08 职场文书
2014年大学生预备党员思想汇报1000字
2014/09/13 职场文书
大学生自我评价范文
2015/03/03 职场文书
2015年建筑工程工作总结
2015/05/13 职场文书
2016年“世界环境日”校园广播稿
2015/12/18 职场文书
MongoDB支持的索引类型
2022/04/11 MongoDB
源码安装apache脚本部署过程详解
2022/09/23 Servers