技术背景

在上一篇博客中,我们介绍了如何使用pyinstaller将python项目打包成一个可执行文件,并且放在系统目录下,让系统用户可以直接识别到我们构造的项目。而python项目中常见的setup.py其实也是在执行类似的构建的功能,通过setup.py文件可以将python包按照指定的方案进行构建,构建出来的可执行文件是一个egg文件。最后将这个egg文件转移到python包的统一管理路径下,这样我们就可以在系统内任一位置的python文件中调用我们构建好的这个python库。

python项目示例

首先我们构造一个大概的目录结构,项目的路径如下所示:

  1. [dechin@dechin-manjaro test_setup]$ tree
  2. .
  3. ├── requirements.txt
  4. ├── setup.py
  5. └── ts
  6. └── __init__.py
  7. 1 directory, 3 files

在一个名为test_setup的路径下,作为我们最上层的项目根目录。然后在根目录下有需求配置文件requirements.txt,我们可以在这个文件中添加我们的python库所依赖的其他python库,如numpyscipy等。而setup.py就是我们这里的安装文件,在后面的章节中会着重提到。最后是我们的项目的核心路径ts,里面包含了我们的核心代码。

用__init__.py文件构造的简单项目

在一个普通的python项目中,我们可以用目录.模块名.函数名的形式来构造python项目的引用方法。但是对于一些比较简单的库而言,比如定义一个二叉树的数据结构这种简单的项目,我们可以直接在__init__.py文件里面直接定义好所有的项目函数及内容。当然,对于一些比较大型的比较规范的项目而言,也会用__init__.py文件作为一个统一的函数入口,以提升模块化项目的可用性。在本测试用例中,我们也定义了一个简单的py核心代码文件如下:

  1. [dechin@dechin-manjaro test_setup]$ cat ts/__init__.py
  2. # __init__.py
  3. def p2(number):
  4. return number ** 2
  5. def p3(number):
  6. return number ** 3

这个名为ts的项目具有两个函数功能:p2用于计算输入参数的平方,以及p3用于计算输入参数的立方。

构造setup文件

我们主要是基于setuptools来实现一个python项目的构建,以下直接展示本项目的构建方法:

  1. # setup.py
  2. import os
  3. from setuptools import setup, find_packages
  4. __version__ = '1.0' # 版本号
  5. requirements = open('requirements.txt').readlines() # 依赖文件
  6. setup(
  7. name = 'ts', # 在pip中显示的项目名称
  8. version = __version__,
  9. author = 'Dechin',
  10. author_email = 'dechin.phy@gmail.com',
  11. url = '',
  12. description = 'ts: Test Setup',
  13. packages = find_packages(exclude=["tests"]), # 项目中需要拷贝到指定路径的文件夹
  14. python_requires = '>=3.5.0',
  15. install_requires = requirements # 安装依赖
  16. )

在这个构建方法中,我们配置了项目的版本号(版本管理)、依赖库、项目名称以及需要进行构建的文件夹。比如这里我们加了一个exclude的选项排除了tests目录(虽然本项目中并没有这个目录,但是一般我们都要剔除测试目录)。当然我们也可以用指定目录进行构建的方法,但是这里不做过多的赘述。

依赖包配置文件

python之所以这么火,很大程度上就得益于其强大的生态,而这些生态都是靠别人搭建好的轮子来支撑起来的。因此大部分的python项目都会依赖于第三方的python包,在安装的时候我们可以仅用一个文件就进行配置:

  1. [dechin@dechin-manjaro test_setup]$ cat requirements.txt
  2. numpy==1.20.1

requirements.txt的配置文件中,我们最好是能够指定一个固定的版本号,这样可以确保软件的兼容性。

执行安装

按照上述的方法对我们的python项目进行编写后,就可以开始执行构建,如果需要测试编译可以先运行python3 setup.py build来进行测试,在安装成功后再执行install指令,当然我们也可以直接一步执行python3 setup.py install指令来进行安装:

  1. [dechin@dechin-manjaro test_setup]$ python3 setup.py install
  2. running install
  3. running bdist_egg
  4. running egg_info
  5. writing ts.egg-info/PKG-INFO
  6. writing dependency_links to ts.egg-info/dependency_links.txt
  7. writing requirements to ts.egg-info/requires.txt
  8. writing top-level names to ts.egg-info/top_level.txt
  9. reading manifest file 'ts.egg-info/SOURCES.txt'
  10. writing manifest file 'ts.egg-info/SOURCES.txt'
  11. installing library code to build/bdist.linux-x86_64/egg
  12. running install_lib
  13. running build_py
  14. creating build/lib
  15. creating build/lib/ts
  16. copying ts/__init__.py -> build/lib/ts
  17. creating build/bdist.linux-x86_64/egg
  18. creating build/bdist.linux-x86_64/egg/ts
  19. copying build/lib/ts/__init__.py -> build/bdist.linux-x86_64/egg/ts
  20. byte-compiling build/bdist.linux-x86_64/egg/ts/__init__.py to __init__.cpython-38.pyc
  21. creating build/bdist.linux-x86_64/egg/EGG-INFO
  22. copying ts.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
  23. copying ts.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
  24. copying ts.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
  25. copying ts.egg-info/requires.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
  26. copying ts.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
  27. zip_safe flag not set; analyzing archive contents...
  28. creating 'dist/ts-1.0-py3.8.egg' and adding 'build/bdist.linux-x86_64/egg' to it
  29. removing 'build/bdist.linux-x86_64/egg' (and everything under it)
  30. Processing ts-1.0-py3.8.egg
  31. Copying ts-1.0-py3.8.egg to /home/dechin/anaconda3/lib/python3.8/site-packages
  32. Adding ts 1.0 to easy-install.pth file
  33. Installed /home/dechin/anaconda3/lib/python3.8/site-packages/ts-1.0-py3.8.egg
  34. Processing dependencies for ts==1.0
  35. Searching for numpy==1.20.1
  36. Best match: numpy 1.20.1
  37. Adding numpy 1.20.1 to easy-install.pth file
  38. Installing f2py script to /home/dechin/anaconda3/bin
  39. Installing f2py3 script to /home/dechin/anaconda3/bin
  40. Installing f2py3.8 script to /home/dechin/anaconda3/bin
  41. Using /home/dechin/anaconda3/lib/python3.8/site-packages
  42. Finished processing dependencies for ts==1.0

安装完成后,我们可以在pip的管理包目录下找到我们所构建的python包:

  1. [dechin@dechin-manjaro test_setup]$ python3 -m pip list
  2. Package Version
  3. ---------------------------------- -------------------
  4. ts 1.0

同时在执行完build指令之后,本地目录下会生成一系列的编译构建目录,如build和dist等:

  1. [dechin@dechin-manjaro test_setup]$ tree
  2. .
  3. ├── build
  4.    └── bdist.linux-x86_64
  5. ├── dist
  6.    └── ts-1.0-py3.8.egg
  7. ├── requirements.txt
  8. ├── setup.py
  9. ├── ts
  10.    ├── __init__.py
  11.    └── __pycache__
  12.    └── __init__.cpython-38.pyc
  13. └── ts.egg-info
  14. ├── dependency_links.txt
  15. ├── PKG-INFO
  16. ├── requires.txt
  17. ├── SOURCES.txt
  18. └── top_level.txt
  19. 6 directories, 10 files

而dist目录下的egg文件在执行完install指令之后,会被拷贝到系统指定的python包管理路径下,我们可以在系统中搜索到这个文件:

  1. [dechin-root test_setup]# find / -name *ts-1.0-py3.8.egg
  2. /home/dechin/anaconda3/lib/python3.8/site-packages/ts-1.0-py3.8.egg
  3. /home/dechin/projects/2021-python/setup/test_setup/dist/ts-1.0-py3.8.egg

这里我们可以看到第一个路径就是python包管理路径。

软件包功能测试

在安装完成后,我们可以在任意的路径下引用到我们构建好的ts项目,比如这里我们可以用ipython来测试一下:

  1. [dechin@dechin-manjaro test_setup]$ ipython
  2. Python 3.8.5 (default, Sep 4 2020, 07:30:14)
  3. Type 'copyright', 'credits' or 'license' for more information
  4. IPython 7.19.0 -- An enhanced Interactive Python. Type '?' for help.
  5. In [1]: from ts import p2, p3
  6. In [2]: p2(4)
  7. Out[2]: 16
  8. In [3]: p3(4)
  9. Out[3]: 64

测试结果表明,我们成功的从编译构建好的ts项目中引用了平方和立方的计算函数。

安装包的删除

跟其他的python包一样,我们可以用pip来统一管理,也可以用pip来直接删除我们自己安装的ts项目:

  1. [dechin@dechin-manjaro test_setup]$ python3 -m pip uninstall ts
  2. Found existing installation: ts 1.0
  3. Uninstalling ts-1.0:
  4. Would remove:
  5. /home/dechin/anaconda3/lib/python3.8/site-packages/ts-1.0-py3.8.egg
  6. Proceed (y/n)? y
  7. Successfully uninstalled ts-1.0

总结概要

一个完善的python项目,不仅需要梳理好核心代码的软件架构,还需要定义好依赖文件、编译构建文件、API接口文档、编码规范门禁等。这里我们介绍了如何用setup.py文件来完善一个最简单的python项目,这也是每一个python开源项目所必须要具备的条件。

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/setup.html

作者ID:DechinPhy

更多原著文章请参考:https://www.cnblogs.com/dechinphy/

Python3基础之构建setup.py的更多相关文章

  1. Python3安装turtle提示错误:Command "python setup.py egg_info" failed with error code 1

    Python3安装turtle提示错误:Command "python setup.py egg_info" failed with error code 1 Python3.5安 ...

  2. python的构建工具setup.py

    一.构建工具setup.py的应用场景 在安装python的相关模块和库时,我们一般使用“pip install  模块名”或者“python setup.py install”,前者是在线安装,会安 ...

  3. rqalpha探究 1 setup.py

    rqalpha是难得几个好的做量化交易的开源项目,不过由于自己python用的实在不多,看起来还是觉得很复杂. 因此准备抽取出框架,从最简单的搭建. 思路 从setup着手,看一下如何建立一个发布工程 ...

  4. python 使用 setup.py 方式安装及包的卸载

     安装:         可通过 --home 或 --prefix 指定安装目录 --prefix=xx/xxx    选择安装目录 --record files.txt   记录所有安装文件的路径 ...

  5. Command "python setup.py egg_info" failed with error code 10

    1:今天系统重装以后,下载了新的版本的python3.6.1.然后想通过pycurl模块测试URL,突然发现windows10下我无法通过pip安装pycurl模块了,报错内容如下 Collectin ...

  6. Command "python setup.py egg_info" failed with error code 1一种问题的解决方法

    问题描述:无论是你在pycharm中直接使用import and install命令,还是pip的时候出现了Command "python setup.py egg_info" f ...

  7. python3基础视频教程

    随着目前Python行业的薪资水平越来越高,很多人想加入该行业拿高薪.有没有想通过视频教程入门的同学们?这份Python教程全集等你来学习啦! python3基础视频教程:http://pan.bai ...

  8. python2 使用pip安装psycopg2出现错误:Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-mvzdNj/psycopg2/

    公司业务需求,开发语言python2,需要使用数据库:postgresql,需要安装模块psycopg2这个模块, 使用pip install psycopg2 报错: Command "p ...

  9. edgedb 内部pg 数据存储的探索 (三) 源码包setup.py 文件

    edgedb 是基于python开发的,同时集成了cython 以下为包的setup.py 配置,从里面我们可以看到关于edgedb 的一些依赖 以及构建过程 setup.py 源码 整体配置不算很多 ...

随机推荐

  1. 如何在 Apple Watch S6上离线播放音乐

    如何在 Apple Watch S6上离线播放音乐 Apple Watch 离线播放音乐 营销策略,捆绑销售 Apple Watch + AirPods + Apple Music Apple Wat ...

  2. iPhone 12 Pro 屏幕时间设置的密码锁出现弹窗 UI 错位重大 Bug

    iPhone 12 Pro 屏幕时间设置的密码锁出现弹窗 UI 错位重大 Bug iOS 14.1 Bug 弹窗 UI 非常丑 弹窗屏占太高了 屏幕使用时间 https://support.apple ...

  3. Ethical Hacking Tutorials

    Ethical Hacking Tutorials Free Ethical Hacking Tutorials https://www.guru99.com/ethical-hacking-tuto ...

  4. Bootstrap5 多级dropdown

    <div class="dropdown"> <a class="btn dropdown-toggle"> Dropdown link ...

  5. ts 在Function上创建静态属性和方法

    interface IMessage { (value: any): void; success(): void; error(): void; version: string; } const Me ...

  6. 图解 git 流程

    图解 git 流程 Github 开源项目 1 动画 2 web repl 3 online git cli & create remote branch # Create a new bra ...

  7. 一条sql语句的执行过程

    一条select语句执行流程 第一步:连接器 连接器负责跟客户端建立连接.获取权限.维持和管理连接.如果用户名密码验证通过后,连接器会到权限表里面查出你拥有的权限.之后该连接的权限验证都依赖于刚查出来 ...

  8. css选择器,过滤筛选

    $('.required:not(.final_price)').each(function() { if (!$(this).val()) { error_count ++; if ($(this) ...

  9. winform解析json API数据

    {  "retCode" : "SUCCESS",  "msg" : "",  "data" : { ...

  10. Linux+Tomcat+Jdk1.8+jenkins环境搭建

    1.下载jdk的rpm安装包,这里以jdk-8u191-linux-x64.rpm为例进行说明 下载地址:https://www.oracle.com/technetwork/java/javase/ ...