Python学习笔记番外:构建你自己的第三方模块

Python学习笔记番外:构建你自己的第三方模块

如之前的博文《Python学习笔记5:模块》所说,Python的第三方模块都在pypi这个网站管理。

pypi的意思即Python Package Index。

那我们是不是也可以构建自己的第三方模块并上传呢?答案是肯定的,软件世界本来就是靠每一个开发者增砖加瓦而来。

pypi上关于打包和上传第三方模块的官方说明文档在这里

创建模块框架

为了演示,我们可以构建一个这样的第三方模块:

image-20210312145726646

其中的文件我们都先保持空白,其用途会在后续填充内容时一一介绍。

pyproject.toml

作为示例,我们可以往这个文件中填充以下内容:

[build-system]
requires = [
    "setuptools>=42",
    "wheel"
]
build-backend = "setuptools.build_meta"

这个文件是第三方模块构建时会用到的配置文件,requires会指定一个包含构建工具版本以及构建时候需要用到的工具等的列表,而build-backend会指定用何种工具构建。

LICENSE

这个文件中的内容是你程序使用的发布许可证,示例中使用的是MIT许可:

Copyright (c) 2018 The Python Packaging Authority

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

关于几个开源许可证之间的关系,可以参考这个说明:

image-20210312161001443

想了解更多关于许可证的内容可以阅读这个知乎问答

README.md

这个文档用于说明你的模块用途和使用方式,和github一样,这个说明文档会直接显示在pypi网站上。

这个示例中说明文档用的是markdown编写,这也是目前非常流行的软件示例文档编写语言,想了解更多可以阅读《从今天开始markdown》。

setup.cfg

组织发布文档的内容有两种方式,静态和动态。静态是通过定义setup.cfg文件来实现,动态是编写setup.py文件。

一般来说推荐使用静态方式,动态仅用于某些特殊情况,比如需要加入一些动态构建信息。

这个示例这种我们使用以下构建信息来填充setup.cfg

[metadata]
# replace with your username:
name = example-pkg-icexmoon
version = 0.0.1
author = Example Author
author_email = author@example.com
description = A small example package
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/pypa/sampleproject
project_urls =
    Bug Tracker = https://github.com/pypa/sampleproject/issues
classifiers =
    Programming Language :: Python :: 3
    License :: OSI Approved :: MIT License
    Operating System :: OS Independent

[options]
include_package_data = False
package_dir =
    = src
packages = find:
python_requires = >=3.6

[options.package_data]
* = *.info

[options.packages.find]
where = src

这是一个最简单地构建信息,我们来介绍一些主要参数:

  • name:你要发布的模块名称,需要在pypi上唯一,所以这里建议加入你自己的名称来保证唯一性。
  • version:你程序版本号。
  • author:这个不用解释了吧。
  • long_description:模块的详细说明,这里可以直接指定到你创建好的说明文档,比如file: README.md
  • long_description_content_type:详细说明内容的类型,这里当然是markdown,我猜测你创建一个html类型的说明文档也是可行的。
  • url:你的项目地址,对个人开发者来说一般是github上的项目地址。
  • project_urls:这里可以定义多个你项目的地址,比如说问题反馈页面之类的。
  • classifiers:模块运行条件,比如Python版本号,操作系统,软件许可证等。
  • package_dir:软件包目录,空表示根目录。
  • packages:模块依赖,可以说明对其它模块的依赖列表,这里可以通过find:来实现对代码自动检索依赖。
  • python_requires:需要的Python版本。
  • where:模块所在目录。
  • options.package_data:需要打包进源码内的非代码文件,这里是和包名一一对应的,但可以使用通配符,比如*=*.txt就表示包含所有包下边的txt文件。
  • include_package_data:是否使用mainfest.in把非代码文件打包进安装程序,这里边牵扯很多问题,官方文档我来回看了好几遍,都没弄清楚include_package_data/package_data/mainfest.in之间的关系。建议不要使用这个。知乎上有篇文章说的有点道理,想了解的可以看这里

更详细的说明请阅读官方文档

setup.py

如之前所说,setup.py用于动态建构模块,但在使用静态构建模块的时候这个文件是可选的,即可有可无,但如果你加入了这个文件,此时也需要加入以下内容,如果没有,则会构建出错:

import setuptools

setuptools.setup()

__init__.py

Python模块下都会包含这个文件,以和普通文件夹进行区分,可以作为模块的入口文件写入初始化代码,也可以保持空文件。

tests

构建测试用文件夹,保持空即可。

构建发布文档

更新相关工具

在构建发布文档之前我们最好更新一下代码构建工具,以使用最新的构建工具构建代码。

在cmd下执行:

python3 -m pip install --upgrade build

如果遇到类似我这样的错误:

image-20210312153805778

说明是因为连接pypi.org超时的原因,这个好像在国内很普遍,因为pip工具默认的timeout选项是15秒,这里我们修改为30秒再请求:

python3 -m pip install --upgrade build --timeout 30

image-20210312153953701

更新成功。

如果pip没更新的,这里最好也更新一下:

python3 -m pip install --upgrade pip --timeout=30

还需要更新一个setuptools,虽然在构建过程中如果setuptools版本过旧,会自动更新,但我天朝的网络环境,懂的都懂,最好还是手动更新一下:

python3 -m pip install --upgrade setuptools --timeout=50

不知道为什么,这个700k左右的小工具下载速度慢的令人发指,而且timeout设置为30的话会失败,所以这里用了50。

构建发布文档

在cmd中将工作目录指向模块的根目录,即本示例中的packaging_tutorial目录,并执行构建命令:

python3 -m build

image-20210312161502636

出现上面的信息就表示构建成功了。

新建的发布文档会出现在模块目录下的dist目录中:

image-20210312162257625

其中whl文件是真正的发布文件,tar.gz是打包的源代码文件,相当于备胎,在某些不能正常安装使用模块的情况下就会使用源码。

上传发布文档

开发中的模块可以现在本地测试妥当后再发布,可以使用命令

pip install markdown_img_icexmoon-0.1.0-py3-none-any.whl --force-reinstall

直接安装本地打好的发布包,通过这种方法安装和从pypi仓库安装是一样的,这样可以绕过pypi仓库直接测试本地开发的模块,验证没问题了再上传pypi仓库。

好了,现在我们需要在pypi上注册一个账户用于发布,但我们这里是进行测试,所以可以使用测试用pypi:

  • https://test.pypi.org/account/register/

注册好后前往这个页面创建一个token:

image-20210312162929355

因为还没有上传项目,所以这里创建一个可以用于所有项目的token:

image-20210312163136750

需要保存好这个token,页面上只会展示一次。

我们还需要安装一个上传用工具:

python3 -m pip install --user --upgrade twine --timeout 100

又是一个很难下的工具,直接超时指定到100

安装好后用以下命令上传发布文档:

python3 -m twine upload --repository testpypi dist/*

正式环境发布可以用这个:

python -m twine upload dist/* --skip-existing
  • --skip-existing可以跳过已发布的版本,只发布没发布的版本

会要求你输入账号密码,账号可以使用__token__,密码就使用token。

现在你就可以在testpypi上看到你上传的项目了:

image-20210312171512387

  • 因为是pypi测试环境,对于用pip安装你构建的模块这一部分内容就不再做演示,如果想尝试的可以阅读官方文档,但最好是构建虚拟pip环境进行尝试,否则可能污染你的模块环境。
  • 想了解更多Python模块的内容的可以阅读《Python学习笔记5:模块
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值