使用pip发布Python程序的方法步骤


Posted in Python onOctober 11, 2018

写过 Python 程序的小伙伴们都知道,需要 import 个非 Python 自带的软件包时,都要用到 pip 这个程序。平时我们都是用 pip,如果我们写好了一个程序,想让大家都能用的到,那么是不是也可以通过 pip 发布出去呢?

答案当然是可以了,这篇文章我们就来看看如何用 pip 发布一个 python 程序。

1. 环境准备

要用 pip 发布 python 程序,首先当然是要安装 Python 和 pip 这两个软件了,以 Ubuntu 16.04 为例:

$ sudo apt update 
$ sudo apt install -y python python-pip

CentOS 和 RedHat 因为 RPM 体系需要依赖于 python,更是默认就安装好了。

另外发布 Pypi,还需要安装一个发布工具, twine ,以及其所依赖的 setuptools、wheel:

$ sudo pip install --upgrade twine setuptools wheel

好,到这环境就已经就绪了。

2. 注册帐号

pip 上传代码包是最终保存在 https://pypi.org 这个网站上的,所以要用 pip 发布程序,就需要在这个网站上注册一个帐号。

访问该网址进行注册: https://pypi.org/account/register/

使用pip发布Python程序的方法步骤

注册后还需要进行邮箱验证,流程和普通网站没有任何区别,所以具体步骤就不在这里详细介绍了。

3. 代码结构

要发布 Python 程序,程序的结构必须符合特定的要求,假设要发布的程序名为 example-pkg,基本的目录结构如下:

/example-pkg
 /example-pkg
  __init__.py
 setup.py
 LICENSE
 README.md

说一下目录和文件的含义:

  • 首先最外层要建立一个和发出程序同名的文件夹: /example-pkg
  • 该文件夹下还要再简历一个同名文件夹,用来存放程序代码: /example-pkg/example-pkg
  • Python 的老规矩,example-pkg/example-pkg 目录下当然要有一个 __init__.py 文件。
  • /example-pkg 目录下要有一个叫 setup.py 的文件,如果下载过 Python 代码包,应该都知道这个文件,需要通过这个文件进行 Python 代码的编译(可能会有依赖的其他代码包或者依赖的 C 文件)和安装。
  • LICENSE 文件:这个文件就是用来保存代码所使用的开源许可证。
  • README.md:这个是软件行业的惯例了,帮助文档。

对于 setup.py 文件,还有必要好好说说,先贴个例子,下面这个例子中,主要是实现了从 /example-pkg/example-pkg/__init__.py 文件中读取 version 参数,来配置当前软件的版本,并指定了代码包名(name)、作者(author)、邮箱(author_email)、描述信息(long_description、long_description_content_type)、依赖(install_requires),以及哪些文件不会被打包到程序中(exclude_package_data)。

另外需要提醒大家一点, 给程序起名字不要带下划线(_) ,python import 代码包时,是不支持下划线包名的,出现这种情况就比较尴尬,代码装上了,还是用不了。

#!/usr/bin/env python

import re
import setuptools

version = ""
with open('example-pkg/__init__.py', 'r') as fd:
  version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
            fd.read(), re.MULTILINE).group(1)

with open("README.md", "r") as fh:
  long_description = fh.read()

setuptools.setup(
  name="example-pkg",
  version=version,
  author="example",
  author_email="author@example.com",
  description="This is the SDK for example.",
  long_description=long_description,
  long_description_content_type="text/markdown",
  url="http://example.com",
  install_requires=[
    'requests!=2.9.0',
    'lxml>=4.2.3',
    'monotonic>=1.5',
  ],
  packages=setuptools.find_packages(exclude=("test")),
  classifiers=(
    "License :: OSI Approved :: MIT License",
    "Intended Audience :: Developers",
    "Operating System :: OS Independent",
    "Programming Language :: Python",
    "Programming Language :: Python :: 2",
    "Programming Language :: Python :: 2.6",
    "Programming Language :: Python :: 2.7",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.3",
    "Programming Language :: Python :: 3.4",
    "Programming Language :: Python :: 3.5"
  ),
  exclude_package_data={'': ["example-pkg/test.py", "example-pkg/config.txt"]},
)

4. 上传和检查

一切准备就绪,下面就可以执行打包命令,产生要上传的代码包了:

$ python setup.py sdist bdist_wheel

执行结束后,会产生如下目录和文件:

/example-pkg/dist/
 example-pkg-0.0.1-py3-none-any.whl
 example-pkg-0.0.1.tar.gz

包有了,就差上传了,执行第一步中安装的 twine 命令:

$ twine upload dist/*
Uploading distributions to https://upload.pypi.org/legacy/
Enter your username: <your pypi.org username>
Enter your password: <your pypi.org password>
Uploading example-pkg-0.0.1-py3-none-any.whl
100%|?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????| 45.0k/45.0k [00:01<00:00, 24.0kB/s]
Uploading example-pkg-0.0.1.tar.gz
100%|?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????| 43.8k/43.8k [00:00<00:00, 46.2kB/s]

上传完毕!不过这里有一点需要注意,上传新版本后,很可能 pip search 还没法查到版本的更新,这是正常的,我理解是

pip search 命令依赖于缓存,所以不会立刻生效。

接下来就让我们下载自己刚刚上传的 python 试试吧:

$ pip install example-pkg
$ python
>>> import example-pkg
>>> example-pkg.name
'example-pkg'

最后再补充一点,上传可能会失败,提示无法上传指定的代码包,此时很大的可能是 pypi 中已经有了相同的代码包,所以建议在上传之前,先搜索一下是否有重名的代码包,选择一个不冲突的名字,再上传。

例如下面这个例子,example-pkg 已经存在了,如果要再上传,那当然会失败,换个名字就解决了。

$ pip search example-pkg
example-pkg (0.0.7)                      - A small example package
......

5. 参考文档

Packaging Python Projects

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python3使用requests包抓取并保存网页源码的方法
Mar 15 Python
Python判断两个list是否是父子集关系的实例
May 04 Python
python使用sessions模拟登录淘宝的方式
Aug 16 Python
对Django的restful用法详解(自带的增删改查)
Aug 28 Python
python使用sklearn实现决策树的方法示例
Sep 12 Python
PYTHON发送邮件YAGMAIL的简单实现解析
Oct 28 Python
pytorch数据预处理错误的解决
Feb 20 Python
pytorch中的inference使用实例
Feb 20 Python
jupyter notebook 增加kernel教程
Apr 10 Python
使用python创建Excel工作簿及工作表过程图解
May 27 Python
如何写python的配置文件
Jun 07 Python
python内置模块之上下文管理contextlib
Jun 14 Python
对python Tkinter Text的用法详解
Oct 11 #Python
python数据批量写入ScrolledText的优化方法
Oct 11 #Python
攻击者是如何将PHP Phar包伪装成图像以绕过文件类型检测的(推荐)
Oct 11 #Python
python中join()方法介绍
Oct 11 #Python
Python中staticmethod和classmethod的作用与区别
Oct 11 #Python
对Python 窗体(tkinter)文本编辑器(Text)详解
Oct 11 #Python
详谈Python 窗体(tkinter)表格数据(Treeview)
Oct 11 #Python
You might like
PHPThumb PHP 图片缩略图库
2012/03/11 PHP
php根据指定位置和长度获得子字符串的方法
2015/03/17 PHP
PHP多进程之pcntl_fork的实例详解
2017/10/15 PHP
laravel框架中表单请求类型和CSRF防护实例分析
2019/11/23 PHP
jQuery学习笔记之jQuery的动画
2010/12/22 Javascript
JS操作select下拉框动态变动(创建/删除/获取)
2013/06/02 Javascript
extjs中form与grid交互数据(record)的方法
2013/08/29 Javascript
javascript计算当月剩余天数(天数计算器)示例代码
2014/01/09 Javascript
js实现文本框只允许输入数字并限制数字大小的方法
2015/08/19 Javascript
使用Sticky组件实现带sticky效果的tab导航和滚动导航的方法
2016/03/22 Javascript
JS定时器实现数值从0到10来回变化
2016/12/09 Javascript
Vue中使用vee-validate表单验证的方法
2018/05/09 Javascript
Vue infinite update loop的问题解决
2019/04/23 Javascript
微信小程序进入广告实现代码实例
2019/09/19 Javascript
vue设置一开始进入的页面教程
2019/10/28 Javascript
[02:16]DOTA2超级联赛专访Burning 逆袭需要抓住机会
2013/06/24 DOTA
Python实现字符串反转的常用方法分析【4种方法】
2017/09/30 Python
Python中%是什么意思?python中百分号如何使用?
2018/03/20 Python
python hook监听事件详解
2018/10/25 Python
python变量赋值方法(可变与不可变)
2019/01/12 Python
详解爬虫被封的问题
2019/04/23 Python
解决pyinstaller打包发布后的exe文件打开控制台闪退的问题
2019/06/21 Python
python实现截取屏幕保存文件,删除N天前截图的例子
2019/08/27 Python
Django通用类视图实现忘记密码重置密码功能示例
2019/12/17 Python
使用CSS3滤镜的filter:blur属性制作毛玻璃模糊效果的方法
2016/07/08 HTML / CSS
探索HTML5本地存储功能运用技巧
2016/03/02 HTML / CSS
详解如何解决H5开发使用wx.hideMenuItems无效果不生效
2021/01/20 HTML / CSS
使用索引(Index)有哪些需要考虑的因素
2016/10/19 面试题
2016公司中秋节寄语
2015/12/07 职场文书
《秋天的图画》教学反思
2016/02/19 职场文书
什么是执行力?9个故事告诉您:成功绝非偶然!
2019/07/05 职场文书
浅谈MySQL next-key lock 加锁范围
2021/06/07 MySQL
Python实现DBSCAN聚类算法并样例测试
2021/06/22 Python
Python Matplotlib绘制条形图的全过程
2021/10/24 Python
Android Flutter实现3D动画效果示例详解
2022/04/07 Java/Android
Redis实现短信验证码登录的示例代码
2022/06/14 Redis