How to write a Python package?

这里记录下如何将自己写的Python程序打包成库,并安装, 参考官方文档Packaging Python Projects

安装流程

首先,我们要有一个文件夹,比如名为mypkg的文件夹。

之后我们需要将我们主要的源文件,比如myml文件夹(比如里面是一些机器学习的算法实现), 添加到mypkg中。

之后我们需要两个辅助文件:setup.pyREADME.md

其中README.md写上项目简短的说明即可。

setup.py需要按照一定的格式写,比如下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import setuptools

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

setuptools.setup(
name="example-pkg-your-username",
version="0.0.1",
author="Example Author",
author_email="author@example.com",
description="A small example package",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/pypa/sampleproject",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
)

之后呢,我们就可以将上面的文件夹打包并发布了,发布之后便可以自行通过pip安装。具体可以参考上面官网的链接。

但是,我们这里可能会有一个需求,那就是,我们可能要持续开发这个库。这样的话,我们可以用pip提供的“Editable” Installs, 如此可以进入“Development Mode”。也即,我们只需要在mypkg上层文件夹下运行pip install -e mypkg就可以直接进入开发模式。这时候我们已经可以在终端(但是记得不要在myml文件下,不然就会无法调用)运行Python, 并直接通过import myml来完成调用。

这里我们对代码进行更改后,只需要在mypkg文件下用命令行运行python setup.py build就可以将新的改动提交上去。最后在我们将项目开发完时,运行python setup.py develop --uninstall将开发版本卸载掉,之后重新打包发布,在安装正式版本即可。

__init__.py文件的写法

首先明确__init__.py文件存在,则其所在的文件夹被自动视为一个package,在运行import package_name之后,其对应的__init__.py首先被调用。

按照文档,最顶层的__init__.py可以只写上库名字:name = "example_pkg"

其他的一般空下,不写任何东西,只是作为一个标识。

也有时候会用于多个submodules的一起调用或者限制调用,具体可以参考Python Cookbook3-Chap10.

测试

在写完需求后,写简单的单元测试来验证API的正确性,同时也避免了通过打印测试的局限性。目前主要用的还是unittest库,结合vscode使用非常方便。

文档

对于一个完整的库来说,文档是必不可少的,这里选用的是用Sphinx来做项目的文档。大致流程可以先参考下这里, 将文档通过Github发布,可以参考Open Source Options的这个教程, 最后还有些细枝末节的问题,可以看这篇文档

上面的教程总体感觉都挺乱的,这里进行下汇总。

Step1: 本地生成

首先安装sphinx: pip install sphinx.

之后在mypkg新建文件夹sphinx, 之后进入该文件夹cd sphinx,并运行sphinx-quickstart, 根据提示输入对应的信息。(这里填错了后面还可以改的)

这时候,可以根据reStructuredText 语法写改sphinx文件夹下的.rst文件,指定生成文档的内容与格式等。

之后修改sphinx/source/conf.py文件设置autodoc,参考这里。因为我在设置的时候没有遇到让加入extensions的提示,所以就手动设置,修改结果如下:

1
2
3
4
5
6
7
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.todo",
"sphinx.ext.viewcode",
"sphinx_rtd_theme",
]

这里还有去掉下面路径设置的注释

1
2
3
import os
import sys
sys.path.insert(0, os.path.abspath('.'))

然后保存(其他设置可以随便找个开源项目看看别人怎么写的,比如requests库),在sphinx文件夹下,终端执行sphinx-apidoc -o ./source ../src/

最后是生成html文件,make html

此时可以打开sphinx/build/html/index.html打开文档。

Step2: 发布文档

发布的方法这篇文档写的比较详细,可以照着作下,我这里并没有测试,而是按照Open Source Options最后一集比较粗暴的方法。

就是在mypkg文件夹下新建一个docs文件夹,之后将html文件夹下的文档全部复制过去,再新建一个.nojekyll文件,之后直接commit, push到github。最后在项目的setting中选择githubpages的设置,选中docs文件夹即可。

之后重新生成文档,同样将html文件夹下的文件全部复制到docs再提交就是了。注意这里.nojekyll文件十分重要,如果没有这个文件(而是选择某个主题),会出现文档页面无法显示的情况。

其他可能有些设置没有提到,可以看下我的ToyData项目的设置。

本文标题:How to write a Python package?

文章作者:不秩稚童

发布时间:2019年07月13日 - 14:09:10

最后更新:2019年07月31日 - 17:41:07

原始链接:http://datahonor.com/2019/07/13/How-to-write-a-Python-package/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

击蒙御寇