欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

setuptools制作whl包实战讲解

程序员文章站 2023-11-07 08:23:34
什么是 whl.whl格式的文件本质上是一个压缩包,里面包含了py文件,以及经过编译的pyd文件。使得可以在不具备编译环境的情况下,选择合适自己的python环境进行安装。我们可以使用我们非常熟悉的pip install 来安装whl包。如:pip install mask_detect_v1.0.whl......

什么是 whl

.whl格式的文件本质上是一个压缩包,里面包含了py文件,以及经过编译的pyd文件。使得可以在不具备编译环境的情况下,选择合适自己的python环境进行安装。我们可以使用我们非常熟悉的pip install 来安装whl包。
如:

pip install mask_detect_v1.0.whl

如何制作whl包

setuptools

Setuptools是Python Distutils的加强版,使开发者构建和发布Python包更加容易,特别是当包依赖于其他包时。用setuptools构建和发布的包与用Distutils发布的包是类似的。包的使用者无需安装setuptools就可以使用该包。
文档:
setuptools
文档里的说明还是比较清楚的,本篇文章就以最近做的一个口罩识别项目为例做一个demo,方便自己也方便读者快速你的打whl包。
项目:
Mask-detection-system
setuptools制作whl包实战讲解
查看项目的工程结构,我们想将所有的python文件和cfg文件夹、weights文件夹,以及一些需要用到的数据如voice文件夹下的wav文件都一并打包到whl包中。
照猫画虎似的,我可以写出这样的setup.py

from setuptools import setup, find_packages

setup(
    name='mask-detection-system-1',
    version='dev_v1.0',
    description='mask detection',
    keywords='mask',
    packages=find_packages(),
    install_requires=[
        'numpy',
        'opencv-python-headless',
        'torch',
        'matplotlib',
        'pycocotools',
        'tqdm',
        'pillow',
        'pydub',
        'pyttsx3'
    ],
        author='CreateLAB',
)

这里需要解释的一个setuptools中的函数就是find_packages(),find_packages()简单的说就是能够查找setup.py所在的根目录下所有的python包。那么什么是python包呢?
包含有__init__.py的文件夹就被称为python包。
使用find_packages()函数能够将根目录下所有的python包都打包起来。这样我就分别在根目录、project文件夹、voice文件夹下都放入了__int__.py,这样我预想就能够实现将所有python文件和音频数据都打包起来的预想。但事实并不是这样。我们可以来看打包后的效果。

python setup.py sdist bdist_wheel

打包好的whl包会出现在dist文件夹中个,我们将其提取,看看里面到底打包了什么?
setuptools制作whl包实战讲解很明显,这与我想要的打包效果不符,主要有以下几个问题:

  • 根目录下的py文件都没有被打包
  • voice文件夹下的音频文件没有被打包
  • 目前只有python文件,那么cfg和weights都没打包进来
    由此可见 find_packages()只能打包python包,python包中只有.py而不包括这个文件夹下 其他的数据文件。并且根目录下的.py文件不会被打包进去。

如何打包数据文件

这里就不得不提到setuptools中 include_package_data、 package_data

  • include_package_data:当指定include_package_data=True时,setuptools会自动提取所有包中所有的指定格式的数据文件,数据文件必须通过MANIFEST.in文件中进行指定。
  • package_data:package_data是一个字典,可以指定想要的数据文件。
    MANIFEST.in的写法:MANIFEST
    我们将include_package_data设为True,并且编写MANIFEST.in
recursive-include ./voice *.wav
recursive-include ./cfg *.cfg
recursive-include ./weights *.pt

将MANIFEST.in放进根目录,再进行打包。奇迹发生了!!!
setuptools制作whl包实战讲解我们想要的数据文件就这样轻松的被打包进去啦!!!
那么我就在像,这样我们还要package_data干个锤子?我理解这就是两种方法,我们现将MANIFEST.in删除掉。尝试使用package_data来打包数据文件。

from setuptools import setup, find_packages

setup(
    name='mask-detection-system-1',
    version='dev_v1.0',
    description='mask detection',
    keywords='mask',
    packages=find_packages(),
    include_package_data=True,
    package_data={
        # 由于voice是一个包,因此无需指定包名
        "": ["./*.wav"],
        # 而cfg并不是一个包,因此需要指定cfg包名
        "cfg": ["./*.cfg"],
    },
    install_requires=[
        'numpy',
        'opencv-python-headless',
        'torch',
        'matplotlib',
        'pycocotools',
        'tqdm',
        'pillow',
        'pydub',
        'pyttsx3'
    ],
        author='CreateLAB',
)

这样也能够将数据文件进行打包,看过公司工程院大佬写的setup.py,大多数都使用的这种方法,因此我个人认为这种方法更为推荐。

如何打包根目录下的python文件

如果根目录下有python文件怎么办呢?
这就需要介绍scripts参数了,scripts能够指定独立存在的文件,也就是不在包里。
现在我们将setup.py改写成如下

from setuptools import setup, find_packages

setup(
    name='mask-detection-system-1',
    version='dev_v1.0',
    description='mask detection',
    keywords='mask',
    packages=find_packages(),
    include_package_data=True,
    package_data={
        # 由于voice是一个包,因此无需指定包名
        "": ["./*.wav"],
        # 而cfg并不是一个包,因此需要指定cfg包名
        "cfg": ["./*.cfg"],
    },
    scripts=["./detect.py",
             "./models.py",
             "./test.py",
             "./train.py",
             ],
    install_requires=[
        'numpy',
        'opencv-python-headless',
        'torch',
        'matplotlib',
        'pycocotools',
        'tqdm',
        'pillow',
        'pydub',
        'pyttsx3'
    ],
        author='CreateLAB',
)

这回舒服了!已经将项目打包成了我想要的形式。
setuptools制作whl包实战讲解当然了,setuptools绝对不只这点玩法,这里我写的就是简单入了个门,希望在自己学会知识的同时能够对其他感兴趣的人有一定的帮助。

本文地址:https://blog.csdn.net/weixin_41722370/article/details/106808509