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使用cookie库操保存cookie详解
Mar 03 Python
用Python创建声明性迷你语言的教程
Apr 13 Python
今天 平安夜 Python 送你一顶圣诞帽 @微信官方
Dec 25 Python
对pycharm代码整体左移和右移缩进快捷键的介绍
Jul 16 Python
pytorch中tensor的合并与截取方法
Jul 26 Python
python读取txt文件,去掉空格计算每行长度的方法
Dec 20 Python
Python学习笔记之错误和异常及访问错误消息详解
Aug 08 Python
在Django admin中编辑ManyToManyField的实现方法
Aug 09 Python
python elasticsearch环境搭建详解
Sep 02 Python
OpenCV+python实现实时目标检测功能
Jun 24 Python
2021年的Python 时间轴和即将推出的功能详解
Jul 27 Python
Django基于Models定制Admin后台实现过程解析
Nov 11 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
使用cookie实现统计访问者登陆次数
2013/06/08 PHP
php使用文本统计访问量的方法
2016/05/12 PHP
你必须知道的Javascript知识点之&quot;深入理解作用域链&quot;的介绍
2013/04/23 Javascript
js控制页面控件隐藏显示的两种方法介绍
2013/10/09 Javascript
node.js使用require()函数加载模块
2014/11/26 Javascript
JS实现滑动菜单效果代码(包括Tab,选项卡,横向等效果)
2015/09/24 Javascript
理解javascript函数式编程中的闭包(closure)
2016/03/08 Javascript
jquery通过name属性取值的简单实现方法
2016/06/20 Javascript
bootstrap使用validate实现简单校验功能
2016/12/02 Javascript
jQuery使用Layer弹出层插件闪退问题
2016/12/22 Javascript
JS表单验证方法实例小结【电话、身份证号、Email、中文、特殊字符、身份证号等】
2017/02/14 Javascript
JQuery事件委托原理与用法实例分析
2019/05/13 jQuery
Postman如何实现参数化执行及断言处理
2020/07/28 Javascript
pyv8学习python和javascript变量进行交互
2013/12/04 Python
python中xrange和range的区别
2014/05/13 Python
Python面向对象编程中关于类和方法的学习笔记
2016/06/30 Python
python 将print输出的内容保存到txt文件中
2018/07/17 Python
Python对CSV、Excel、txt、dat文件的处理
2018/09/18 Python
通过python爬虫赚钱的方法
2019/01/29 Python
Appium+python自动化怎么查看程序所占端口号和IP
2019/06/14 Python
python pandas模块基础学习详解
2019/07/03 Python
python执行scp命令拷贝文件及文件夹到远程主机的目录方法
2019/07/08 Python
python实现把二维列表变为一维列表的方法分析
2019/10/08 Python
python模块导入的方法
2019/10/24 Python
django 数据库返回queryset实现封装为字典
2020/05/19 Python
PyQt5如何将.ui文件转换为.py文件的实例代码
2020/05/26 Python
Python SMTP配置参数并发送邮件
2020/06/16 Python
HTML5引入的新数组TypedArray介绍
2012/12/24 HTML / CSS
详解canvas绘图时遇到的跨域问题
2018/03/22 HTML / CSS
如何让Java程序执行效率更高
2014/06/25 面试题
酒店执行总经理岗位职责
2013/12/15 职场文书
学校大课间活动方案
2014/01/30 职场文书
主持人演讲稿
2014/05/13 职场文书
2014年度安全生产目标管理责任书
2014/07/25 职场文书
2015婚礼主持词开场白
2015/05/28 职场文书
SpringBoot工程下使用OpenFeign的坑及解决
2021/07/02 Java/Android