TOC

模块

    Python模块其实指的就是Python的程序文件,一个Python程序一般由很多个文件组成,那么这些文件其中有一个文件,我们称之为顶层文件,顶层文件的意思是,对于Python而言每个程序都可以作为一个单独执行都程序文件,一般来讲,我们为了能够使得整个程序变得清晰,不可能把一个很大的程序都写在一个程序文件中,因此,就把那些公共的函数、类等等,放在一个或多个程序文件中,而后由某一个程序文件来调用并使用他们,所以以后去设计这种大型程序时,通常都基于这种思路来实现;
    那么这个负责去调用其他程序文件中的代码来实现程序功能的,也就是整个程序的入口,也称之为顶层程序文件,那除了顶层文件之外,其余的就是各种模块文件了,其实顶层文件,从某种意义上来讲,也是一个模块文件,它也可以被其他文件所载入,所以它也是模块文件;
    因此对于Python而言,所谓模块,就是一个一个独立的程序文件,模块在物理上表现为,以.py结尾代码文件,之所以将这些代码程序划分开来,就是将程序实现多个有组织的、彼此之间互相独立,但是又能够通过import语句等语句,互相载入,以完成交互的代码片段;
    那么这彼此之间各自独立的自我包含的有组织的代码段,我们就称之为模块,一个文件就可以被看作一个独立的模块,而一个模块通常指的是某一个Python程序文件,模块的文件名至关重要,因为模块的名称就是模块的文件名;
查看标准库:
    >>> help('modules')
标准/内置模块
    当我们在安装Python时,其实Python已经安装了一些标准模块,像Centos7系统默认的Python标准模块路径为/usr/lib64/python2.7,通过sys.path也可以看到,该目录在我们的Python环境变量中,所以我们每次安装完成之后就可以直接使用import语句来使用标准模块;
    Python还有一个比较特殊的内置模块,对于标准的模块Python仅仅是帮我们安装到了Python的模块搜索路径,还是需要我们手动导入,那么对于Python其实还提供了内置模块,连导入的工序都省略了,比如print函数,其实我们都python有一个名为builtins的模块,我们可以简单理解为,在Python启动之初,系统就自动帮我们使用了from builtins import *,所以我们就可以直接使用内建函数而不需要重新导入;
>>> import builtins
>>> builtins.print("cce")
cce
>>> print("cce")         
cce

常见程序架构

    Python允许导入其他模块以实现代码重用,从而也实现了将独立的代码文件组织成更大的程序系统,这个导入的过程,其实背后有编译、装载以及初始化各种对象的这么一个过程,在Python中一切皆对象,所以模块本身也是对象,模块自己有属性,有方法,因为这种对象一定是由某个类实例化出来的,在一个模块顶层定义的所有变量,都在被导入时,成为了被导入的模块属性;
顶层文件:包含了程序的主要控制流程;
模块文件:为顶层文件或其他模块提供各种功能性组件;

wKiom1XBRJGz2Zm6AAD7hBgGV_4239.jpg

  • 注意:模块首次导入(或重载)时,Python会立即执行模块文件的顶层程序代码,但只会声明函数或者类对象,函数体内的代码不会执行,只有函数被调用后才会执行

模块执行环境

    模式是需要被导入的,但是模块也可以导入和使用其他模块,所以这种导入是一种链式关系,能够被Python程序文件导入的模块可以用Python语言开发,它也完全可以是其他语言开发,比如使用C语言发开的代码,它要是开发为Python可导入的模块,那么Python也一样可以导入;
    模块内部可以包含变量、函数、类,而函数和类又可以包含变量等其他元素,但是需要注意的是,我们真正想使用模块时,这个模块内部就不应该有除函数、类之外的代码,因为我们在使用import导入这个模块的时候,这些除了类、函数之外的代码都会执行的,比如这个模块内部,有一个for循环,那么如果我们在外部导入这个模块的时候,就会执行,因为它在模块文件的顶层,所以我们不应该将非变量、函数、类放在顶层文件中;

导入模块
    在导入模块时只能使用模块名,而不能使用带.py后缀的模块文件名,使用import语句就可以导入指定模块了,导入之后Python解释器会生成一个以模块名命名的名称空间;
语法:
    导入模块:import module1,[module2...moduleN]
    模块重命名:import module as module_alias
    导入部分属性:from module import name1,[name2...nameN]
Import工作机制
    Import语句在导入模块时,会执行三个步骤,第一,找到模块,也就是在指定路径下搜索模块文件,第二,编译成字节码,文件导入时就会编译,因此,顶层文件的.pyc字节码文件在内部使用之后会丢弃,只有被导入的文件才会留下.pyc文件,第三部,执行模块的代码来创建其所定义的对象,一个模块应该包含有变量、函数、类,所以在第三步,变量赋值语句会执行,函数声明语句会执行并生成一个函数对象,类声明语句也会执行并生成一个类对象,但是这些函数或者类内部的代码段是不会执行的,只有顶层代码代码执行,从头到尾;
    但是以上的三个步骤,只有在第一次导入模块的时候执行,所以模块重复导入是没有意义的,因为后续的导入操作,无非就是提取内存中已加载的模块对象而已,而不会真正重新去导入它,Python解释器,在Import模块时,首先会去程序的主目录去找,其次到python的环境变量去找,然后还会去python内部的标准链接库目录寻找,而这些目录全部保存在sys.path中;

Python包

    Python中的包,主要用于实现,将一组模块归并到一个目录中,这个目录就叫做一个包,此目录即为包,目录名即为包名,包是一个有层次的文件目录结构,它定义了一个由模块和子包组成的Python应用程序环境;
    基于包,Python在执行程序导入时可以指定模块的导入路径,如:import dir1_name.dir2_name.module_name,dir1_name则是最外层的包名,dir2_name为子包名,module_name为模块文件名,因此Python包可以便捷的将一类具有特定关联的模块放在一起,来生成一个功能更强大,并且自我组织的目录结构,这就叫做包;

    如上,py_pkg_mod是一个python包搜索的路径, 要使用package1这个包,那么py_pkg_mod这个路径必须要在模块搜索路径中,也就是说package1这文件所在的位置,必须是Python模块搜索路径的某个目录下面,所以py_pkg_mod应该是sys.path里面的一个路径,那么我们导入模块的时候,只需要导入package1.mod1就可以了
    包导入语句的路径内的每个目录内都必须有__init__.py文件,__init__.py可包含python代码,但通常为空,仅用于扮演包初始化、替目录产生模块命名空间以及使用目录导入时实现from *行为的角色;
初始化文件详解
    对于包有一个__init__.py的特殊文件,这个文件其实很有用,可以对环境进行初始化,也可以告知使用者,这个包所提供的功能模块,那么在日常开发中,主要是用在后者,告知使用者,这个包那些功能是有用的,可以被调用的,哪些功能是不建议被调用的,因为它是为了完成主线任务所产生的辅助性的功能;
    __init__.py文件可以创建一个__all__的列表,可以将方法名或者模块名,或者子包名以字符串的形式组合起来,然后其他用户在引用这个包的时候,使用from modname import *的时候,默认就会导入__all__列表里面的子包或者模块;
    当__all__不存在时,那么就是常见的,全部导入,当__all__存在时以__all__的元素为准;
# 应用程序层级
[cce@doorta py] tree                
├── main.py
└── mod
    ├── __init__.py
    ├── core1.py
    ├── core2.py
    └── core3.py
[cce@doorta py] cat mod/core1.py
num=1
[cce@doorta py] cat mod/core2.py
num=2
[cce@doorta py] cat mod/core3.py
num=3
# 初始化文件
[cce@doorta py] cat mod/__init__.py 
__all__ = [ "core1" , "core2" ]
# 主程
[cce@doorta py] cat main.py
from mod import *

print(core1.num)
print(core2.num)
print(core3.num)
# 可以看到,包内部的模块,如果没有加入__all__的话,在外部使用from mod import *是导入不成功的
[cce@doorta py] python3.5 main.py
1
2
Traceback (most recent call last):
  File "main.py", line 5, in <module>
    print(core3.num)
NameError: name 'core3' is not defined

包管理

    一开始我们安装Python的时候,会自带的安装很多标准模块,有了这些标准模块之后,我们就可以利用它完成一些基本的需求,但是,业务场景很多,需求也不同,Python内部的标准模块不满足我们需求,所以就会涉及到定制模块,所以呢Python官方就提供了一个官方的平台,这个平台就会存储很多第三方的包和模块,程序员可以将自己写的实现特定功能的代码的包和模块,上传到该平台,这样就带来了极大的便利;
    但是呢,这也带来一个问题,当我们要使用这个第三方包的时候,我们需要在上面手动下载,然后安装到当前的Python环境,这是比较麻烦的,所以Python官方专门给我们提供了一个包管理工具,它主要的作用是管理第三方包和模块,比如说我们可以通过这么一个工具自动到官方提供的平台去检索第三方模块,自动下载并安装到当前的Python环境,同时呢,它也可以将我们自己写好的包和模块,去发布到这个平台里面去;
    那么比较流行的有三个这样的工具,distutils、setuptools和distribute,distutils是Python官方所研发的,它的主要作用就是为了让用户更好的去管理第三方模块,这个项目是1998年开始研发,但是到了2000就开始停止开发了,它主要的功能特点是直接在命令行使用一个setup.py的文件,完成Python包的管理,但是它只能处理简单的包管理逻辑;
    因为distutils从2000年就停止研发了,但是大众有迫切需求,所以有很多网友就自行去开发了这么一种功能的项目,那么其中比较突出的,也是目前最为主流的setuptools,它也属于一个第三方库,所以我们想使用它必须得先安装它才可以,它的更新迭代是比较频繁的,社区也比较活跃,并且它也提供了很多高级功能,比如自动依赖处理,另外还包括了egg分发格式,除此之外还提供了一个easy_install命令简化了Python安装第三方包的步骤;
    但是呢setuptools随着时间的推移更新时间也比较慢了,所以就导致了当Python3出来之后,它还并不支持Python3,于是有很多网友,就将setuptools的代码fork了一份,创建了名为distribute的库,修复了原来setuptools出现的问题,同时声明支持Python3,但是它依然数据第三方库,所以在使用之前还需手动安装,在2013年的时候,setuptools和distribute两个项目的开发组织决定将distribute合并到setuptools,所以的依旧是setuptools,到目前为止有很多包管理项目,但是目前官方认可的就两个,distutils和setuptools;
    distutils是使用setup.py进行安装的,setuptools它是目前包管理的一个事实标准,而且它自身带了一个easy_install命令,使用它可以便捷的安装第三方模块,后来将pip这样的一个安装命令代替了它,同时setuptools还引入了egg格式,只不过后来出现了一个whl的格式来代替它;
常见的三方包形式
    distutils是使用setup.py进行安装的,setuptools功能更加全面,对于目前来讲它已经是包管理的一个事实标准,而且它自身带了一个easy_install命令,使用它可以便捷的安装第三方模块,后来将pip这样的一个安装命令代替了它,同时setuptools还引入了egg格式,只不过后来出现了一个whl的格式来代替它;
    那么常见发布第三方包的形式大致有三种,第一种源码格式,同时源码还分为但文件模块和多文件模块,但文件模块就类似一个单独但模块,而多文件模块一般就是使用包管理工具所发布的项目,那么对于源码格式的形式都有一个特点,那就是这个源码里面肯定是包含了setup.py这样的一个文件,setuptools也是基于它的,第二种是egg格式,egg格式setuptools所引入的一种包的格式,setuptools会识别egg格式的包并且去安装它,第三种,就是whl,其实它的产生就是为了取代egg格式,它本质就是一个zip压缩格式;
常见三方包的安装方式
    上述说明了Python的第三方包有众多格式,那么对应的安装方式也是有所不同的,有离线安装,同时也有在线安装,具体如下;
单文件模块:直接复制到指定的模块搜索路径即可;
多文件包:基于distutils工具发布,包含setup.py文件;
egg格式:直接使用setuptools提供的easy_install进行安装,安装时可能会出现下载以来包都情况;
whl格式:本质是zip,主要是用来代替egg,使用pip进行安装,安装时可能会出现下载以来包都情况;
在线安装:pip和easy_install都可以通过安装源自动下载并安装,常见的国内源有阿里、豆瓣、清华大学等;
单文件模块
    对于单文件模块的安装它的安装方式就比较简单,我们只需要将所需安装的但文件模块,拷贝到特定的目录下就可以,这个特定的模块也就是Pyhton的模块的搜索路径,使用sys.path就会返回一个列表集,将包放置在里面任何一个路径都可以,一般第三方模块都会存放在Python安装目录的site-packages目录下;
多文件包
    对于多文件的包,我们可以使用python setup.py install将包安装到当前Python全局环境,本质就是使用distutils进行包安装的,其实python setup.py install是由两个阶段组成的,第一个阶段是build,第二个阶段是install,但是这两个步骤可以使用一个install进行表示,如果说没有执行build,直接执行install,它仍然会显示build的过程,install会自动触发build的过程,当我们去执行python setup.py build的时候,它会在我们所在的目录下进行build,而build之后会生成一个build目录;
    对于install的过程就非常简单了,仅仅是将编译好的文件,给它复制到指定的模块安装目录中,在未指定安装路径的时候,模块的将安装到当前Python安装第三方模块的默认位置,默认地址通常为Lib/site-packages目录下,可以通过sys.path来查看,对于不同的环境可能不一样,如果我们需要定制化安装,install也专门提供了选项;
# build
--build-base:指定build目录,build会创建build目录,如果说期望在别的地方进行build,保持源码的整洁程度,可以使用此参数,build完成之后会生成一个lib目录,此文件用于保存即将安装的模块文件的,其中lib模块用于保存纯Python语言所研发的模块,因为它的跨平台的,如果说Python代码有一些非Python代码,比如C++等,那么编译完成之后会是lib.platform里面;

# install
--user:将模块安装到用户的家目录的相关目录当作;
--prefix:自定义安装路径,指定Python文件的安装路径;
--exe-prefix:指定与Python无关的,由其他语言所实现的,和平台有关的,已经编译好的相关文件安装路径;
egg格式
    egg是setuptools所引入的一个格式,那么在安装此类格式的软件包之前,我们需要首先安装setuptoos,然后使用easy_install mod.egg安装即可;
whl格式
    whl格式可以使用pip安装,同时也可以使用easy_install进行安装,他们都是可以自动解决依赖的,当在解决依赖时,需要连入网络,到互联网下载模块包;

disutils模块

    disutils模块能够帮助程序员完成程序模块或程序的发布,发布指的就是一个文本的集合,这些文件联合在一起使用disutils可以构建、打包成一个自我包含的发布模块、压缩包文件等等;
    创建好发布包之后可以用于安装,也可以上传的PyPI与他人共享,PyPI就是python的仓库,各种公共发布的第三方模块都在里面存储;
创建发布
    要想创建一个发布的话,首先要将各代码文件组织到一个模块容器中,还需准备一个README或者README.txt文件,里面随便写一些帮助信息,比如作者信息、使用信息等,当然即使是空的也没关系,然后还需要在容器中创建一个setup.py的文件,而后就可以执行打包了,setup.py示例如下;
参数
    要对一个项目打包,需要在项目目录下面给定几个文件,主要是用来提供打包的信息的,比如要打包的模块、包的描述、包的使用权等等,大概有如下几个类,具体的请查询disutils官方文档;
setup.py:主要用来描述包的信息,比如包的名称,作者名称,版本信息等;
    name:包的名称(必须);
    version:包的版本号(必须);
    author:作者名称;
    author_email:作者电子邮箱;
    maintainer:维护者名称;
    maintainer_email:维护者邮箱;
    url:包的主页;
    description:包的简短描述;
    long_description:包的详细描述;
    download_url:包的下载位置;   
    py_modules:打包的工程里面可能存在独立的模块文件,那么此时我们就需要将打包的模块名字写进来,不写默认不会一起打包,这个参数是各独立的模块名称组成的列表,此模块可能位于包根目录下(modname);
    packages:打包的工程里面可能存在多个子包,那么此时,我们也需要将这个要打包的子包名写入到该参数中,该参数也是一个列表,直接写入子包名即可;
    license:许可证;
    platforms:适用的平台列表;
    data_files:需要打包的数据文件列表;
README.rst:主要是对long_description进行修饰的;
LICENSE.txt:声明库对使用责任等等,比如所有权归属,是否可进行商业用途等;
MANIFEST.in:配置是否包含打包文件,类似nginx的include,可忽略;
示例
# setup.py
from distutils.core import setup

setup(
    name="testmod",
    version="0.0.1",
    author="cce",
    author_email="mail0426@163.com",
    py_modules=["testmod"],
    url="blog.doorta.com",
    description="A simple module"
)
查看帮助
[root@node1 cce]# python3.5 setup.py --help-formats # 获取帮助;
[root@node1 cce]# python3.5 setup.py --help-commands # 获取所有可使用的命令;
[root@node1 cce]# python3.5 setup.py bdist COMMAND --help # 获取特定命令的帮助;
[root@node1 cce]# python3.5 setup.py bdist COMMAND --help-formats # 获取特定命令的格式;
命令行参数
    distutils支持很多种打包格式,所以其参数也比较丰富,但是较新的格式distutils是不支持的,比如egg或者whl,但是比较好的是setuptools是支持的,并且setuptools还兼容了distutils原有的打包格式,所以他们包含了共有参数和独有参数,具体如下;
# 共有参数
    sdist:源码打包
        zip:将源码打包为一个zip文件,不进行编译;
        gztar:将源码打包为一个tar.gz文件,不进行编译;
        bztar:将源码打包为一个tar.bz2文件,不进行编译;
        ztar:将源码打包为一个tar.z文件,不进行编译;
        tar:将源码打包为一个tar文件,不进行编译;
    bdist:打包格式类型
        gztar:将源码编译,并打包成tar.gz的自解压格式的压缩包;
        bztar:将模块编译,并打包成一个tar.bz2自解压格式的压缩包;
        ztar:将源码编译,并打包成一个tar.z自解压格式的压缩包;
        zip:将源码编译,并打包成一个zip自解压格式的压缩包;
        rpm:将源码编译,并打包成rpm自解压格式的包;
        pkgtool:将源码编译,并打包成Solaris的自解压格式的压缩包;
        wininst:将源码编译,并打包成windows上能够自解压的zip格式的包;
        msi:将源码编译,并打包成Microsoft Installer,windows上的可安装程序;
# distutils独有参数
    bdist_dumb:将源码编译,并打包成自解压格式的tar、tar.gz、tar.bz2等格式的包,格式通过--fromat指定;
    bdist_rpm:将源码编译,并打包成自解压格式的rpm包;
    bdist_wininst:将源码编译,并打包成windows上能够自解压的zip格式的包;
    bdist_msi:将源码编译,并打包成自解压格式的Microsoft Installer程序,在windows上的可直接安装解压;
# setuptools独有参数
    bdist_egg:将源码编译,并打包成支持easy_install支持的egg格式的包;
    bdist_wheel:将源码编译,并打包成支持pip和easy_install支持的whl格式的包;
实例
    下面就使用disutils打包自定义包,并将其打包成各种格式的案例;
# 创建一个容器
[root@node1 containers]# mkdir containers
# 创建一个包
[root@node1 containers]# mkdir cce
# 创建初始化文件
[root@node1 containers]# touch cce/__init__.py
# 创建核心程序
[root@node1 containers]# cat >> cce/getcce.py << EOF
def getinfo():
    return "cce"
EOF
# 创建README文件
[root@node1 containers]# echo "testmod" > cce/README.txt
# 创建setup.py文件
[root@node1 containers]# cat >> cce/setup.py << EOF
from distutils.core import setup

setup(
    name=          "cce",
    version=       "0.0.1",
    author=        "caichangen",
    author_email=  "mail0426@163.com",
    py_modules=    ["getcce"],
    url=           "http://blog.doorta.com",
    description=   "A simple module"
)
EOF
# 开始打包
[root@node1 containers]# python3.5 setup.py sdist
[cce@doorta cce] ls dist 
cce-0.0.1.tar.gz
# 使用bdist打包
[root@node1 cce]# python3.5 setup.py bdist
[root@node1 dist]# ls
cce-0.0.1.linux-x86_64.tar.gz
[root@node1 dist]# tar xf cce-0.0.1.linux-x86_64.tar.gz 
[root@node1 dist]# tree 
├── cce-0.0.1.linux-x86_64.tar.gz
└── usr
    └── local
        └── python352
            └── lib
                └── python3.5
                    └── site-packages
                        ├── cce-0.0.1-py3.5.egg-info
                        ├── getcce.py
                        └── __pycache__
                            └── getcce.cpython-35.pyc
# 使用bdist打包成rpm格式
[root@node1 cce]# python3.5 setup.py bdist --formats=rpm
[root@node1 cce]# ls dist/
cce-0.0.1-1.noarch.rpm  cce-0.0.1-1.src.rpm  cce-0.0.1.tar.gz
[root@node1 cce]# rpm -qpl dist/cce-0.0.1-1.noarch.rpm 
/usr/local/python352/lib/python3.5/site-packages/__pycache__/getcce.cpython-35.opt-1.pyc
/usr/local/python352/lib/python3.5/site-packages/__pycache__/getcce.cpython-35.pyc
/usr/local/python352/lib/python3.5/site-packages/cce-0.0.1-py3.5.egg-info
/usr/local/python352/lib/python3.5/site-packages/getcce.py
[root@node1 cce]# rpm -qpi dist/cce-0.0.1-1.noarch.rpm 
Name        : cce
Version     : 0.0.1
Release     : 1
Architecture: noarch
Install Date: (not installed)
Group       : Development/Libraries
Size        : 1264
License     : UNKNOWN
Signature   : (none)
Source RPM  : cce-0.0.1-1.src.rpm
Build Date  : Wed 06 Jan 2021 12:52:51 PM CST
Build Host  : node1.doorta.com
Relocations : /usr 
Vendor      : caichangen <mail0426@163.com>
URL         : http://blog.doorta.com
Summary     : A simple module
Description :
UNKNOWN
# 安装模块
[root@node1 dist]# rpm -ivh cce-0.0.1-1.noarch.rpm
# 测试模块
[root@node1 dist]# python
>>> import getcce
>>> getcce.getinfo()
'cce'

打包发布工具

    disutils是官方所提供的一个打包工具,由于其功能较为简洁,第三方市场也就有了setuptools这个升级版,可以扩展disutils的功能,对于目前来讲,已经是一个三方包管理工具的一个事实,但需要知道的是它基本完全兼容disutils的一部分功能,它还可以打包egg格式和whl格式的Python三方模块包;
    twine是一个发布工具,它可以将我们本地打包好的Python包直接提交给pypi平台,和pypi无缝对接,直接使用pip安装即可,但是它只支持windows版本,好在我们的python setup.py 可以直接上传,对于Mac用户也一样可以直接上传包到Pypi平台;
setuptools
    兼容disutils的一个第三方打包工具,安装setuptools直接在官方提供的三方包平台下载setuptools并使用python setup.py install安装即可;
# 常见一个与项目同名的打包目录(重要)
[cce@doorta study] mkdir ccelib
[cce@doorta study] cd ccelib
# 在打包目录创建一个项目
[cce@doorta ccelib] mkdir -p ccelib/tools
[cce@doorta ccelib] touch ccelib/{main.py,tools/{__init__.py,sumdata.py}}
[cce@doorta ccelib] tree
└── ccelib
    ├── main.py
    └── tools
        ├── __init__.py
        └── sumdata.py
[cce@doorta ccelib] cat ccelib/tools/sumdata.py     
data=1
[cce@doorta ccelib] cat ccelib/main.py 
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from ccelib.tools import sumdata
def ret():
    return sumdata.data
# 准备setup.py描述文件
[cce@doorta ccelib] cat setup.py 
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from setuptools import setup

setup(
    name="ccelib",
    version="1.0.3",
    description="test mode",
    packages=["ccelib","ccelib.tools"],  # 需要打包的子包
    py_modules=["ccelib.main"],  # 需要打包的单文件模块
    author="BrYan",
    author_email="mail0426@163.com",
    long_description="this is test module"
)

# 打包成tar格式文件
[cce@doorta ccelib] python3.5 setup.py sdist --formats=gztar
# 安装ccelib模块
[cce@doorta ccelib] pip3 install dist/ccelib-1.0.0.tar.gz
# 使用ccelib模块
>>> from ccelib import main
>>> main.ret()
1
# 打包egg格式文件
[cce@doorta ccelib] python3.5 setup.py bdist_egg
# 安装egg格式
[cce@doorta dist] easy_install-3.5 ccelib-1.0.0-py3.5.egg
# 打包whl格式
[cce@doorta ccelib] python3.5 setup.py bdist_wheel
# 安装whl格式
[cce@doorta dist] pip install ccelib-1.0.0-py3-none-any.whl 
[cce@doorta dist] easy_install ccelib-1.0.0-py3-none-any.whl
发布第三方模块
    使用twine可以将我们的第三方模块发布到官方的第三方平台上面,但是twine只有在windows提供命令工具,支持不是特别的友好,但是好在我们直接使用原生distutils就可以直接上传,如下就分别介绍windows平台和macos平台进行发布;
# windows平台
# 分别打包三种格式
[cce@doorta ccelib] python3.5 setup.py sdist --formats=gztar
[cce@doorta ccelib] python3.5 setup.py bdist_egg 
[cce@doorta ccelib] python3.5 setup.py bdist_wheel  
[cce@doorta ccelib] ls dist 
ccelib-1.0.0-py3-none-any.whl   ccelib-1.0.0-py3.5.egg          ccelib-1.0.0.tar.gz
# windows上使用使用twine将包上传到pypi,twine即可上传

# macos平台
# mac上传首先需要准备一个配置文件,然后直接使用python命令上传
[cce@doorta ccelib] cat ~/.pypirc  
[distutils]
index-servers=pypi
[pypi]
repository = https://upload.pypi.org/legacy/
username = caichangen
password = cai19960426cce
# 打包并上传tar格式
[cce@doorta ccelib] python setup.py sdist --formats=tar upload -r pypi
# 打包并上传egg格式
[cce@doorta ccelib] python3.5 setup.py bdist_wheel upload -r pypi
# 安装上传的包
[cce@doorta ccelib] pip3 install ccelib -i https://pypi.python.org/simple
  • 注意:对于发布Python包和发布模块不同,setup.py需要放在包的外面,并且包内在使用import语法的时候,需要以包名为起始,也就是包的模块寻址路径是包名,而非子包名;

导出项目依赖

    在很多时候,我们在开发项目的时候都会用到很多第三方模块,当项目在部署的时候,新的机器新的环境,可能会出现缺少依赖模块的问题导致整个项目运作不起来,所以就出现了一个第三方模块,pipreqs,它的主要功能就是将当前项目用到的所有模块以及版本号记录下来,并存储为一个requirements.txt文件,当我们将项目代码拿到一个新环境的时候就可以直接将这些模块进行安装了,并且pip对于文件读取模块信息的支持也是不错的,那么pip结合pipreqs就可以很好很快的解决项目依赖的问题,具体如下;
# 安装pipreqs
[cce@doorta ccelib] pip3 install pipreqs
# 进行项目的根目录将所使用的模块导出
[cce@doorta ccelib] pipreqs               
INFO: Successfully saved requirements file in /usr/local/Project/study/ccelib/requirements.txt
# 当项目拿到新环境的时候就可以直接使用pip进行安装了
[cce@doorta ccelib] pip3 install -r requirements.txt

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注