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实现备份文件实例
Sep 16 Python
跟老齐学Python之关于类的初步认识
Oct 11 Python
在Python中使用mongoengine操作MongoDB教程
Apr 24 Python
简单掌握Python的Collections模块中counter结构的用法
Jul 07 Python
python抓取网站的图片并下载到本地的方法
May 22 Python
Flask框架响应、调度方法和蓝图操作实例分析
Jul 24 Python
python ftp 按目录结构上传下载的实现代码
Sep 12 Python
python导入坐标点的具体操作
May 10 Python
介绍一款python类型检查工具pyright(推荐)
Jul 03 Python
django 前端页面如何实现显示前N条数据
Mar 16 Python
django实现HttpResponse返回json数据为中文
Mar 27 Python
python 实现的车牌识别项目
Jan 25 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
浅谈apache和nginx的rewrite的区别
2013/02/22 PHP
CodeIgniter控制器之业务逻辑实例分析
2016/01/20 PHP
PHP实现的进度条效果详解
2016/05/03 PHP
thinkPHP模板中for循环与switch语句用法示例
2016/11/30 PHP
php实现的证件照换底色功能示例【人像抠图/换背景图】
2020/05/29 PHP
js跨浏览器实现将字符串转化为xml对象的方法
2013/09/25 Javascript
微信小程序 删除项目工程实现步骤
2016/11/10 Javascript
ajax实现加载页面、删除、查看详细信息 bootstrap美化页面!
2017/03/14 Javascript
JavaScript实现随机点名程序
2020/03/25 Javascript
[01:02:48]2018DOTA2亚洲邀请赛 4.1 小组赛 A组 LGD vs OG
2018/04/02 DOTA
[03:11]TI9战队档案 - Alliance
2019/08/20 DOTA
在Python的Django框架中包装视图函数
2015/07/20 Python
详解python之配置日志的几种方式
2017/05/22 Python
python输入错误密码用户锁定实现方法
2017/11/27 Python
Python 实现使用dict 创建二维数据、DataFrame
2018/04/13 Python
python批量替换多文件字符串问题详解
2018/04/22 Python
使用Python处理Excel表格的简单方法
2018/06/07 Python
用Python将一个列表分割成小列表的实例讲解
2018/07/02 Python
set在python里的含义和用法
2019/06/24 Python
python调用c++返回带成员指针的类指针实例
2019/12/12 Python
python GUI库图形界面开发之PyQt5开发环境配置与基础使用
2020/02/25 Python
python实现快递价格查询系统
2020/03/03 Python
python实现飞机大战项目
2020/03/11 Python
python3.8.1+selenium实现登录滑块验证功能
2020/05/22 Python
Python加载数据的5种不同方式(收藏)
2020/11/13 Python
Under Armour安德玛荷兰官网:美国高端运动科技品牌
2019/07/10 全球购物
乐高西班牙官方商店:LEGO Shop ES
2019/12/01 全球购物
施华洛世奇巴西官网:SWAROVSKI巴西
2019/12/03 全球购物
高二生物教学反思
2014/01/27 职场文书
公司端午节活动方案
2014/02/04 职场文书
《埃及的金字塔》教学反思
2014/04/07 职场文书
植树造林的宣传标语
2014/06/23 职场文书
小学生自我评价100字(15篇)
2014/09/18 职场文书
企业法人代表证明书
2014/09/27 职场文书
python单元测试之pytest的使用
2021/06/07 Python
深入理解pytorch库的dockerfile
2022/06/10 Python