0%

打包python应用

设计,构建,测试以及维护一个应用要做很多的工作。可重用性是Python的生存方式,据此该如何打包自己的应用并发布给其他人安装使用呢?

自己的应用目录结构如下。目录project现在可以被拷贝至一个新的目录,且立刻被复用。但为了方便他人安装,我们需要打包这个应用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.\dirname
| src
| .\projectname
│ __init__.py

├─bin
│ start.py
│ __init__.py

├─conf
│ config
│ __init__.py

├─core
│ auth.py
│ main.py
│ __init__.py

├─db
│ __init__.py

├─lib
│ __init__.py

└─log
__init__.py

安装必须的环境

有许多工具可以完成这项任务,如1998年首次添加到Python标准库的原始构建和分发系统distutils,虽然直接使用distutils正在淘汰,但它仍然为当前的打包和分发基础架构奠定了基础;setuptools在很大程度上是作为distutils的取代者,2004年首次发布,目前它被推荐来替代distutils

本文使用setuptools来打包应用。安装命令如下。

1
2
# 安装最新版本setuptools
$ pip install --upgrade setuptools

打包应用

Python以一种特殊的格式组织打包应用,以便于方便安装和使用。基本流程如下。

  1. 在项目目录外创建一个文件夹,用于存放项目。当为自己的包选一个名字要避免包名冲突。此处以projectname为例。

  2. project目录移到projectname目录。

  3. 创建README.md文件。

  4. 创建一个LICENSE文件。

  5. 创建setup.cfgsetup.py文件。

    详细说明如何构建和安装应用程序,对这两个文件详细解释可参考[setuptools文档](setuptools documentation)。

    创建pyproject.toml,示例如下。

    1
    2
    3
    4
    5
    6
    [build-system]
    requires = [
    "setuptools",
    "wheel"
    ]
    build-backend = "setuptools.build_meta"

    setup.cfg示例如下。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    [metadata]
    # replace with your username:
    name = projectname
    version = 0.0.1
    author = Yaohuanyu
    author_email = yaohuanyuchn@gmail.com
    description = A small example package
    long_description = file: README.md
    long_description_content_type = text/markdown
    url = http://blog.jcxy.ml/
    project_urls =
    Bug Tracker = http://blog.jcxy.ml/
    classifiers =
    Programming Language :: Python :: 3
    License :: OSI Approved :: MIT License
    Operating System :: OS Independent

    [options]
    ; package_dir包名称和目录的映射。空包名表示为根目录
    package_dir =
    = src
    include_package_data = true
    packages = find:
    python_requires = >=3.6

    [options.packages.find]
    where = src

    setup.py(以前是必须的,现代setuptools可以省略)为了兼容,增加此文件。示例如下。

    1
    2
    3
    from setuptools import setup

    setup()
  6. 创建一个名为MANIFEST.in的文件以包含资源文件。

    示例如下。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    include *.rst *.txt *.md LICENSE VERSION *.pyx
    recursive-include src/projectname/bin *.py
    recursive-include src/projectname/conf *.py
    recursive-include src/projectname/core *.py
    recursive-include src/projectname/db *.py
    recursive-include src/projectname/lib *.py
    recursive-include src/projectname/log *.py
    recursive-include docs *
    recursive-exclude * __pycache__
  7. 构建应用包。

    采用如下命令构建应用包。

    1
    2
    3
    4
    5
    # *.tar.gz
    $ python setup.py sdist

    # *.wheel
    $ python setup.py bdist_wheel

    会在Project/dist目录中创建一个名为projectname-0.0.1.tar.gz的文件。

使用自己的包

在虚环境下通过pip install命令安装自己的包。

1
$ pip install projectname-0.0.1.tar.gz

通过pip卸载包

1
$ pip uninstall projectname

发布自己的应用

当完成打包和测试,准备分享可以这样做。

  • 通过邮件将打好的包发送给朋友。
  • 将这个包上传至自己的网站。
  • 发布到公共仓库,如PyPI。可以参考教程