6

Python 打包分发工具 setuptools 简介

 3 years ago
source link: https://mathpretty.com/13655.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Python 打包分发工具 setuptools 简介

所属分类:Python库介绍

摘要本文会介绍 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 = "[email protected]",
  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'

下面是 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

我们首先在清单文件 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

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

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

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

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'

这样在安装完毕之后,我们可以直接在控制台输入 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
  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK