前言
setuptools可以帮助我们创建和分发Python包,而当用户在使用setuptools创建的包时,就可以像调用标准库或者是python第三方库那样直接使用,并不需要安装setuptools,只要一个启动模块就可以
一、简介以及安装
1-1、简介
Setuptools 是 Python 的一个包管理工具,用于创建、分发和安装 Python 包。它扩展了 Python 标准库中的 distutils,使其更易于使用和扩展,并提供了额外的功能,如自动解决依赖关系和插件系统。
使用 Setuptools 可以帮助你完成以下任务:
- 创建 Python 包:Setuptools 允许你定义 Python 包的元数据(如包名称、版本、作者、描述等),并提供一个用于构建包的命令行工具 setup.py。
- 安装 Python 包:Setuptools 提供了一个命令行工具 easy_install,可以自动下载和安装 Python 包及其依赖项。另外,Setuptools 还可以与其他包管理工具(如 pip)协同工作,以便更好地管理 Python 包的依赖关系。
- 分发 Python 包:Setuptools 允许你将 Python 包发布到 PyPI(Python 包索引)或其他类似的仓库中,以便其他人可以轻松地安装和使用你的包。
- 自动解决依赖关系:Setuptools 可以自动解决 Python 包的依赖关系,以确保包及其依赖项都正确地安装和配置。
- 插件系统:Setuptools 提供了一个插件系统,允许开发人员编写并安装扩展 Setuptools 功能的插件。
总之,Setuptools 提供了一种简单、可靠的方式来创建、分发和管理 Python 包。如果你经常开发 Python 项目或库,Setuptools 是一个不错的选择,可以帮助你更好地管理项目依赖项,以及将代码分享给其他人。
1-2、安装以及升级
安装 Setuptools 通常可以通过 pip 工具完成。在命令行中输入以下命令:
pip install setuptools
升级:
pip install --upgrade setuptools
二、源码包介绍
首先python库的打包分发方式有两种:源码包source dist(sdist)、二进制包binary dist(bdist)。
2-1、源码包sdist
2-1-0、创建 setup.py 文件(简单介绍,详细在第三节)
创建 setup.py 文件:在你的库的根目录下创建一个名为 setup.py 的 Python 脚本文件,并定义你的库的元数据(如名称、版本、作者、描述等)以及依赖项。
from setuptools import setup, find_packages setup( name='your-library-name', version='0.1.0', author='your name', description='Your library description', packages=find_packages(), install_requires=[ 'dependency1', 'dependency2' ] )
注意:在上述代码中,find_packages() 方法可以自动查找你的库中的所有包,install_requires 参数指定了你的库所依赖的其他包。
2-1-1、打包成源码包sdist(构建源码包)
python setup.py sdist # 源码包sdist就是我们熟悉的.zip、.tar.gz等后缀文件,就是一个压缩包。 # setup.py 在第三里会介绍,它指定了打包分发的一些配置信息。 # 不指定格式的话,sdist会根据当前平台创建默认格式,在类 Unix 平台上,将创建后缀名为.tar.gz分发包,而在Windows上为 .zip 文件。 # 加参数可以指定文件格式 --formats=gztar
2-1-2、安装源码包
打包后的文件在新生成的dist文件夹下,以及多了一些中间临时配置信息(egg-info文件)
先把源码包进行解压缩,之后再执行setup.py
python setup.py install
或者是用pip命令直接安装源码包
pip install xxx.zip # notice:该命令会将当前的Python应用安装到当前的Python环境的“site-packages”目录下,这样其他程序就可以像导入标准库一样导入该应用的代码了
2-2、二进制包bdist
2-2-0、创建 setup.py 文件(简单介绍,详细在第三节)
from setuptools import setup, find_packages setup( name='your-library-name', version='0.1.0', author='your name', description='Your library description', packages=find_packages(), install_requires=[ 'dependency1', 'dependency2' ], entry_points={ 'console_scripts': [ 'your-command-name=your_package_name.module_name:function_name', ], }, )
注意:在上述代码中,entry_points 参数指定了你的库所提供的命令行工具。
2-2-1、打包成源码包bdist
与源码包相比,二进制包的特点是不用再编译,也就是安装更快。
# python目前主流的二进制包格式是wheel(.whl后缀),它的前身是egg。wheel本质也还是一个压缩包,可以像zip一样解压缩。还有其他一些格式诸如rpm、wininst等。 # 在使用wheel之前,需要先安装wheel: pip install wheel # 这里以打包成rpm格式为例: python setup.py bdist --format=rpm # 等价于 python setup.py build_rpm # 等价于 python setup.py bdist_rpm # 还有目前的主流二进制包,wheel是目前官方推荐的打包方式。 python setup.py build_wheel # 等价于 python setup.py bdist_wheel # 生成源码包的路径和sdist相同 # eg: 如果使用bdist_wininst,打出来的是exe安装文件,可以点击安装
2-2-2、安装源码包bdist
pip install xxx.whl
三、setup文件以及相关参数介绍
3-1、setup文件简介
构建前的结构应该包含:
# notice: 应该包含文件夹:demo、dist、docs,包含代码文件setup.py
setup.py文件:
# encoding: utf-8 from setuptools import setup, find_packages import refrigerator_apc setup( # name: 应用名, 即包名 name='refrigerator_apc', # version:版本号 version=refrigerator_apc.__version__, # 包括在安装包内的Python包 packages=find_packages(), # author:作者名 author='wang', # author_email: 作者邮箱 # description: 描述 # url: 项目主页 # python_requires: 对python版本进行限制。 python_requires='>=3.6', platforms='any', # install_requires: 自动安装依赖 install_requires=[ "pandas", "numpy", ] )
3-2、setup其他参数介绍
3-2-1、find_packages()函数和find_namespace_packages()函数
这两个函数都是用来指定packages参数的,而packages参数是用来指示打包分发时需要包含的package,类型为list[str]
1、find_packages()函数:
# 只会打包包含__init__.py的package以及setup.py文件 # notice:假设包含__init__.py的文件夹里还有一个文件data,data文件夹里没有__init__.py,那么data文件将不会被打包 from setuptools import setup setup( packages=find_packages() )
2、find_namespace_packages()函数
# 为了打包所有的文件,我们会使用find_namespace_packages()函数 from setuptools import setup setup( packages=find_namespace_packages() # notice: 如果只想指定某个文件夹,那么我们可以直接在find_namespace_packages中加参数。 # packages=find_namespace_packages('src') )
3-2-2、include_package_data(MANIFEST.in)
find_packages()函数和find_namespace_packages()函数打包的是源码文件和setup.py文件。非源码文件(如.dat和.txt文件)需要别的参数(include_package_data)来打包
# include_package_data:bool类型,默认为True,当为True时,根据MANIFEST.in文件来打包分发库
3-2-3、MANIFEST.in 文件介绍
# define: 该文件指定了一些语法规则,主要是用来打包非源码文件的 # include pat1: 添加与任何列出的模式匹配得所有文件 exclude pat1: 删除 recursive-include dir-pattern pat1: 递归dir-pattern及其子文件夹,添加 recursive-exclude dir-pattern pat1: 删除 graft dir-pattern: 添加匹配目录下的所有文件 prune dir-pattern: 删除 global-include pat1 # eg: include src/pack1/*.txt # 更多信息请参考结尾第二个链接
3-2-4、依赖包安装与版本管理
from setuptools import setup,find_packages setup( # 表明当前模块依赖哪些包,若环境中没有,则会从pypi中自动下载安装 # 只包含包名,这种形式只检查包的存在性,不检查版本。 install_requires=['numpy'] # setup.py本身要依赖的包,这里列出的包,不会自动安装 setup_requires = [''] # 测试时使用的依赖 # 执行python setup.py test时,可以自动安装,确保测试的正常运行 tests_require=[ # 自动保持版本为最新 'pandas>=3.1.1' # 指定了版本,把风险降到了最低,确保了开发,测试与部署的版本一致,不会出现意外,但是不利于更新。 'tensorflow==2.7.1' ] )
参考文章: