Python 打包分发工具 setuptools 简介

王 茂南 2021年6月20日07:16:48
评论
5242字阅读17分28秒
摘要本文会介绍 Python 的标准打包及分发工具 setuptools。会介绍 setup.py 文件的格式,以及四种安装的方式。

简介

作为 Python 标准的打包及分发工具,setuptools 可以说相当地简单易用。它会随着 Python 一起安装在你的机器上。你只需写一个简短的 setup.py 安装文件,就可以将你的 Python 应用打包。

参考资料

 

setup.py 文件编写

这一部分我们直接来看一个 setup.py 文件的例子,然后对这个文件做出详细的解释:

  1. from __future__ import absolute_import
  2. from __future__ import division
  3. from __future__ import print_function
  4. from setuptools import setup, find_packages
  5. import os
  6. here = os.path.abspath(os.path.dirname(__file__)) # 将 setup.py 放在项目的根目录
  7. setup(
  8.     name = "test",
  9.     version = "1.0",
  10.     keywords = ("test", "xxx"),
  11.     description = "eds sdk",
  12.     long_description = "eds sdk for python",
  13.     license = "Apache License, Version 2.0",
  14.     url = "http://test.com",
  15.     author = "test",
  16.     author_email = "test@gmail.com",
  17.     packages = find_packages(),
  18.     include_package_data = True,
  19.     install_requires=[i.strip() for i in open(os.path.join(os.path.dirname(__file__), 'requirements.txt')).readlines() if i.strip()],
  20.     entry_points = {
  21.         'console_scripts': [
  22.             'test = test.help:main'
  23.         ]
  24.     }
  25. )

下面是 setup.py 中各个参数的解释:

  • 基础描述信息
    • name 包名称(起一个响亮的名字)
    • version (-V) 包版本
    • author 程序的作者
    • author_email 程序的作者的邮箱地址
    • maintainer 维护者
    • maintainer_email 维护者的邮箱地址
    • url 程序的官网地址
    • license 程序的授权信息
    • description 程序的简单描述
    • long_description 程序的详细描述
    • platforms 程序适用的软件平台列表
    • keywords 程序的关键字列表
    • classifiers 程序的所属分类列表
  • 包的进阶信息
    • packages 需要处理的包目录(包含__init__.py的文件夹),这里通常使用 find_packages(),它默认在和setup.py同一目录下搜索各个含有 __init__.py的包。
    • install_requires = ["requests"] 需要安装的依赖包。我们可以首先生成 requirements.txt 文件,接着使用生成的文件生成需要的参数。关于生成 requirements.txt 文件,可以参考Python自动生成requirements.txt文件
    • include_package_data,引入非 Python 文件。默认情况下只会对 Python 源码进行打包,但是如果我们想要将其他静态文件,例如 css 文件,或是 qt 的一些 ui 文件打包进去,就需要使用这个参数。后面会有详细的介绍。
  • 制作命令行工具
    • entry_points 动态发现服务和插件,可以用来制作命令行工具。也就是我们可以通过一些简单的命令,来运行 Python 项目中的指定文件或是函数。下面会详细进行介绍。

 

packages 的说明(自动搜索 Python 包)

我们指定 packages 后会自动将指定的 package 下的源代码进行打包。但是有的时候会有很多 subpackage,这个时候 setuptools 提供了 find_packages 来找到所有的 subpackages。下面图展示了大概的效果:

Python 打包分发工具 setuptools 简介

 

include_package_data(引入非 Python 文件)

默认情况下我们的打包只会对源码进行打包。如果我们还想将其他非 Python 文件也打包,比如静态文件(JS,CSS,图片),应该怎么做呢?这时我们要在项目目录下添加一个 MANIFEST.in 文件夹。假设我们把所有静态文件都放在 static 子目录下,现在的目录结构如下所示:

  1. setup-demo/
  2.   ├ setup.py         # 安装文件
  3.   ├ MANIFEST.in      # 清单文件
  4.   └ myapp/           # 源代码
  5.       ├ static/      # 静态文件目录
  6.       ├ __init__.py
  7.       ...

我们首先在清单文件 MANIFEST.in 中,列出想要在包内引入的目录路径:

  1. include myapp/static *.css # 只包含 static 文件夹中的 css 文件
  2. recursive-include myapp/xxx * # 递归包含

这里有一点需要注意,最后的文件夹不要加斜杠,也就是不能写成 myapp/static/ 这种形式,一定是要写成 myapp/static 这种形式。

上面recursive-include表明包含子目录。别急,还有一件事要做,就是在 setup.py 中将 include_package_data参数设为 True:

  1. #coding:utf8
  2. from setuptools import setup
  3. setup(
  4.     name='MyApp',         # 应用名
  5.     version='1.0',        # 版本号
  6.     packages=['myapp'],   # 包括在安装包内的Python包
  7.     include_package_data=True    # 启用清单文件MANIFEST.in
  8. )

之后再次打包或者安装,myapp/static 目录下的所有文件都会被包含在内。如果你想排除一部分文件,可以在 setup.py 中使用exclude_package_date参数,比如:

  1. setup(
  2.     ...
  3.     include_package_data=True,    # 启用清单文件MANIFEST.in
  4.     exclude_package_date={'':['.gitignore']}
  5. )

上面的代码会将所有 .gitignore 文件排除在包外。如果上述 exclude_package_date 对象属性不为空,比如{'myapp':['.gitignore']},就表明只排除 myapp 包下的所有 .gitignore 文件。

 

MANIFEST 文件语法

上面我们讲了利用 MANIFEST 来引入非 Python 文件。但除了引入之外,我们还可以排除一些文件。下面是完整的 MANIFEST 的语法:

  • include pat1 pat2 ...,Add all files matching any of the listed patterns (Files must be given as paths relative to the root of the project)
  • exclude pat1 pat2 ...,Remove all files matching any of the listed patterns (Files must be given as paths relative to the root of the project)
  • recursive-include dir-pattern pat1 pat2 ...,Add all files under directories matching dir-pattern that match any of the listed patterns
  • recursive-exclude dir-pattern pat1 pat2 ...,Remove all files under directories matching dir-pattern that match any of the listed patterns
  • global-include pat1 pat2 ...,Add all files anywhere in the source tree matching any of the listed patterns
  • global-exclude pat1 pat2 ...,Remove all files anywhere in the source tree matching any of the listed patterns
  • graft dir-pattern,Add all files under directories matching dir-pattern
  • prune dir-pattern,Remove all files under directories matching dir-pattern

 

 

install_requires 的说明(自动安装依赖)

这个参数是在 setup.py 文件中指定依赖,然后在使用 setuptools 安装应用时,依赖包的相应版本就会被自动安装。但是通常情况下,手动写依赖会比较麻烦,我们可以使用 pipreqs 首先自动生成 requirement.txt 文件,接着读取这部分文件即可

  1. install_requires=[i.strip() for i in open(os.path.join(os.path.dirname(__file__), 'requirements.txt')).readlines() if i.strip()],

 

entry_points 的说明

entry_points 可以用来创建控制台脚本。我们看上面的例子就会非常好理解:

  1. entry_points = {
  2.         'console_scripts': [
  3.             'test = test.help:main'
  4.         ]
  5. }

这样在安装完毕之后,我们可以直接在控制台输入 test,这样是可以运行 test.help 模块下的 main 函数。

 

执行安装文件

在有了上面的 setup.py 文件之后,我们就可以进行打包,也可以将应用安装在本地的 Python 环境中了。一共有以下的四种安装方式:

创建 egg 包

下面的命令会在当前目录下的 dist 目录内创建一个 egg 文件。文件名格式就是 应用名-版本号-Python版本.egg。同时你会注意到,当前目录多了 build应用名.egg-info 子目录来存放打包的中间结果。(主要是看 dist 目录下的内容)

  1. python setup.py bdist_egg

 

创建 tar.gz 包

这个命令和上例类似,只不过创建的文件类型是 tar.gz,文件名为 应用名-版本号.tar.gz也是保存在 dist 文件夹下。

  1. python setup.py sdist --formats=gztar

 

安装应用

下面的安装命令会将当前的 Python 应用安装到当前 Python 环境的 site-packages 目录下,这样其他程序就可以像导入标准库一样导入该应用的代码了

  1. python setup.py install

这里我们如果想要删除安装的包,可以使用 pip uninstall xxx 来完成删除。

 

以开发方式安装

如果应用在开发过程中会频繁变更,每次安装还需要先将原来的版本卸掉,这样就会很麻烦。如果使用 develop 开发方式安装的话,应用代码不会真的被拷贝到本地 Python 环境的 site-packages 目录下,而是在 site-packages 目录里创建一个指向当前应用位置的链接。这样如果当前位置的源码被改动,就会马上反映到 site-packages 里。

  1. python setup.py develop

我们还可以使用 pip install -e 这种方式来「已开发方式安装」。这里 -e 的含义是,Install a project in editable mode (i.e. setuptools "develop mode") from a local project path or a VCS url.

例如我们进入要安装的库所在的文件夹,使用下面的命令进行安装:

  1. pip install -e .

 

  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin
王 茂南
  • 本文由 发表于 2021年6月20日07:16:48
  • 转载请务必保留本文链接:https://mathpretty.com/13655.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: