一、介绍

  Python项目的打包、发布和部署的常用方法比较:

  1. distutils - python自带的基本安装工具, 适用于非常简单的应用场景使用, 不支持依赖包的安装
      通过distutils来打包,生成安装包,安装python包等工作,需要编写名为setup.py python脚本文件。
  2. setuptools - 针对 distutils 做了大量扩展, 尤其是加入了包依赖机制。不支持python3,安装完setuptools后会有easy_install
  3. distribute - 类似于setuptools,支持python3,安装完distribute后会有easy_install。
  4. easy_install - setuptools 和 distribute 自带的安装脚本, 也就是一旦setuptools或distribute安装完毕, easy_install 也便可用了。
  5. pip - 目标是取代easy_install。easy_install 有很多不足: 安装事务是非原子操作, 只支持 svn, 没有提供卸载命令, 安装一系列包时需要写脚本; pip 解决了以上问题, 已俨然成为新的事实标准, virtualenv 与它已经成为一对好搭档;
  6. distutils2 - setuptools 和 distribute 的诞生是因为 distutils 的不济, 进而导致目前分化的状况。它将成为 Python 3.3 的标准库 packaging , 并在其它版本中以distutils2 的身份出现; 换句话说, 它和 pip 将联手结束目前混乱的状况。
  7. virtualenv - 用来创建隔离的python环境,处理python环境的多版本和模块依赖。

本文主要介绍了基于setuptools 通过pip+wheel的方式对python项目进行打包。

二、打包步骤

2.1 前提条件

2.1.1 python环境准备

1、首先要确定你机器上已经安装了python环境,可通过以下命令查看本机的python版本:
win+R 进入cmd命令行 -> 进入python安装目录 -> 输入命令 python 查看python 版本
1

2.1.2 pip安装

注:如果有出现‘‘pip‘ 不是内部或外部命令,也不是可运行的程序或批处理文件’异常时,
处理方案:‘pip‘ 不是内部或外部命令,也不是可运行的程序或批处理文件 – 解决方案.

  1、pip是python的一个模块,在使用之前,要确认一下该模块是否存在:
输入命令:python -m ensurepip
2
   2、将pip升级:
输入命令:python -m pip install --upgrade pip
3

2.1.3 wheel安装

   Wheel 也是一种 built 包,而且是官方推荐的打包方式。也许你曾经遇见或使用过 egg 包,但现在 wheel 是官方推荐的打包方式(https://wheel.readthedocs.io/en/stable/)。
wheel 包的优点:
    1.更快地安装纯 Python 和本机 C 扩展包。
    2.避免安装时执行任意代码。 (避免 setup.py)
    3.在 Windows 或 macOS 上安装 C 扩展不需要编译器。
    4.为测试和持续集成提供更好的缓存。
    5.创建 .pyc 文件作为安装的一部分,以确保它们与使用的 Python 解释器匹配。
    6.跨平台和机器的更一致的安装。

使用 wheel 打包,首先要安装 wheel,输入命令:pip3 install wheel
6

2.2 编写setup.py文件

  在项目与src平级的目录下新增文件setup.py:
4
  编辑setup.py文件内容:

from setuptools import setup, find_packages
setup(
    name='firstApp',  # 应用名
    version='1.0.0',  # 版本号
    packages=find_packages('src'),  # 包含所有src中的包
    package_dir={'': 'src'},  # 告诉distutils包都在src下

    # 打包时需要打包的数据文件,如图片,配置文件等
    package_data = {
        # 任何包中含有.txt文件,都包含它
        '': ['*.xml'],
    },
    # 项目依赖的 Python 库,使用 pip 安装本项目时会自动检查和安装依赖
    install_requires=['numpy'],
    # 指定项目依赖的 Python 版本。
    python_requires='>=3',
    # 是否使用静态文件,为true时静态文件生效,否则不起作用
    include_package_data=True,
    # 此项需要,否则卸载时报windows error
    zip_safe=False,
    setup_cfg=True
     #其他信息暂时没加,后面会加附录进行说明
)

  文件格式内容说明,参考链接: Python打包分发工具setuptools.

另外,为了测试,我们在src下面加个python包,目录结构及内容如下:
新增包结构:myapp
新增文件:init.py 和greet.py
8
greent.py编辑内容为:
def hello(): print('Hello, welcome to setuptools!')
9

2.3 分发

  有了上面的 setup.py 文件,我们就可以打出各种安装包,主要分为两类:sdist 和 bdist。

使用 bdist 可以打出 built distribution,和源码包相比,由于预先构建好,所以安装更快:
5
使用上,和 sdist 一样,可以使用 --formats 指定包格式。如:python setup.py bdist --formats=rpm
同时为了简化操作,setuptools 提供了如下命令:
6
所以打 rpm 包可以使用:python setup.py bdist_rpm

  使用wheel打包,命令行进入待打包的工程目录,
输入命令:python setup.py sdist bdist_wheel
2
成功后 /dist目录存在两个文件:
9

  执行成功后,目录下除了 dist 和 *.egg-info 目录外,还有一个 build 目录用于存储打包中间数据。wheel 包的名称如 firstApp-1.0.0-py3-none-any.whl,其中 py3 指明只支持 Python3。
  可以使用参数 --universal,包名如 firstApp-1.0.0-1.0.0-py2.py3-none-any.whl,表明 wheel 包同时支持 Python2 和 Python3。使用 universal 也成为通用 wheel 包,反之称为纯 wheel 包。

注:应用开发过程中会频繁变更,每次安装都需要先卸载旧版本很麻烦。使用 develop 开发模式安装的话,实际代码不会拷贝到 site-packages 下,而是除一个指向当前应用的链接(*.egg-link)。
这样当前位置的源码改动就会马上反映到 site-packages。使用如下:python setup.py develop
如需卸载,使用 pip uninstall

2.4 安装 Wheel

  可以使用 pip 安装到本地 Python 的 site-packages 目录,命令:pip install dist/文件名.whl
这里我的命令是:pip install dist/firstApp-1.0.0-py3-none-any.whl
10
安装成功后,会在python安装路径/Lib/site-packages目录下看到功能模块:
11

2.5 使用

  现在和其他使用 pip 安装的三方库一样使用:
测试内容:

import myapp.greet as a
a.hello()

12
输出为:
13

以上就是 Python 打包和分发的全部内容,当然是最简单的功能。更复杂的打包,比如模块过滤,非 py 文件打包,作者信息等常见的需求,都被实现在 setup() 内。
详细介绍 setup()可参考链接: Python打包分发工具setuptools.

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐