Skip to main content

从零开始:Python模块开发、打包 和 PyPI发布

· 6 min read
Ferdinand Su

前言

因为计算方法实验的缘故,需要用python写一些简单的算法,并进行实验、记录实验数据。其中一个实验需要记录一些多项式,而友好得显示公式的一个好办法就是产生Markdown文件。

然而python自带的Markdown库貌似更侧重于解析,不适合这种轻量化的写入性操作,因此决定自己造一个快速生成Markdown文件的库,也就是pyLabOn

python模块的开发

理论上,一个文件就是一个python模块。但是更复杂的Python Package是由一个包含__init__.py的文件夹构成的。

我们在pyCharm中新建一个Python Package, 就是这种形式的。

然后我们添加功能性的源文件,对于pyLabOn而言,就是 LabReport.py

模块和文件信息

文件信息由头部的多行注释完成:

@File    :   LabReport.py
@Contact : ferdinandsu@outlook.com
@License : (C)Copyright 2020 HIT-ReFreSH

@Modify Time @Author @Version @Description
------------ ------- -------- -----------
2020-5-15 Ferdinand Sukhoi 0.1.4 Light-weight tool to generate markdown-formatted lab reports.
"""

模块的信息由以下语句说明:

__all__ = ['Report', 'ReportParagraph', 'ReportPlainContent', 'ReportTable']
__version__ = '0.1.4'
__author__ = 'Ferdinand Sukhoi'

__all__说明模块对外公开的内容,version和author说明版本和作者。

文档注释

像C# xmldoc, javadoc等一样,python也有文档注释。 对于类(以Report为例):

class Report(ReportParagraph):
"""A markdown report file
Attributes:
MarkdownFilePath: full-path of the markdown file
PDFPath: full-path of the PDF file
"""

对于函数,是:

    def add_table(self, headers, data, align=0):
"""
Create and add a table to this paragraph
:param headers: Headers of the table
:type headers: list[str]
:param data: Data of the table
:type data list[list[str]]
:param align: Optional. Align of the table, default 0-Central
:type align: list or int
:return: The table added
:type ReportTable
"""

这样,对于一个模块的源文件而言,元素是完全的了。

__init__.py的内容

这个是模块本身对应的文件。

对于pyLabOn而言,它应该包括:

from .LabReport import *

__all__ = ['Report', 'ReportParagraph', 'ReportPlainContent', 'ReportTable']
__version__ = '0.1.4'
__author__ = 'Ferdinand Sukhoi'

python的打包和发布

打包

在包根目录下新建 setup.py , 其中包含以下内容:


from setuptools import setup, find_packages

setup(
name = "pylabon",
version = "0.1.4.3",
keywords = ["markdown", "HIT-ReFreSH"],
description = "To generate markdown-formatted lab reports.",
long_description = "Light-weight tool to generate markdown-formatted lab reports. For python.",
license = "MIT",

url = "https://github.com/HIT-ReFreSH/pyLabOn",
author = "Ferdinand Sukhoi",
author_email = "FerdinandSu@outlook.com",

packages = find_packages(),
include_package_data = True,
platforms = "any",
install_requires = ["pypandoc"]
)

其中字段和对应说明如下:

字段说明
name包的名称,必须小写
version版本号
keywords关键词
description说明
long_description长说明
license许可协议,比如MIT
url项目地址,写github就行
author作者
author_email作者邮箱
packages包含的包,直接=find_packages()自动生成就行
include_package_data是否包含包信息
platforms适用平台,一般写any即可
install_requires安装的依赖项,list

本地安装

本地安装只需

python setup.py install

即可。

打包和发布到PyPI

本部分将利用Github Actions自动化完成。

注册PyPI账号

PyPI官网注册账户,记住用户名和密码。

向Github仓库添加secrets

在仓库的Settings->Secrets里增加:

PYPI_USERNAME:你的PyPI用户名 PYPI_PASSWORD:你的PyPI密码

添加CI

向仓库添加如下CI:

# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

name: deploy

on:
push:
branches:
- master # Default release branch

jobs:
deploy:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
python ./pyLabOn/setup.py sdist bdist_wheel
twine upload dist/*

注意倒数第二行 setup.py 的位置是相对于仓库根目录的。

完成发布

提交、推送到github,你的软件包会自动发布到PyPI。PyPI的更新和审核(真的有审核吗...)很快。

通过PyPI安装发布的软件包

运行

pip instal <PackageName>

即可。

总结

以上就是Python模块的开发、打包以及发布,与Nuget体验基本上差不多了,都很方便、友好、快速。

不知道比某些J开头的语言高到哪里去了。