Python的日常:模块、包、打包

将程序拆分成多个相互独立的代码片段,这些片段就是模块。Python中的模块,表现为.py文件。模块的名字就是文件的主文件名。

模块可以被其它文件/模块导入,以组织成更大的系统。导入其它模块的文件为“顶层程序文件”。模块本身也是对象,在被导入的时候,其全局对象会变为其自身的属性或方法,也就是说,可以用点号运算符调用模块中的全局对象(全局函数,全局变量等)。

其中,被导入的模块,既可以是用Python实现的,也可以是其它语言,如C、C++等。

将一堆模块归结到一个目录中,这个目录就叫做包。
包是一个有层次的文件目录结构,基于包,可以这样指定模块导入路径:import 包名.子包名.模块。注意,要想让这个package被搜到到,其所在的目录必须存在于sys.path列表中。

8.1. 模块

import语句用于导入指定模块,导入后生成一个以模块名字命名的名字空间:

import和from import可以嵌套在其他语句中,如果需要的话。其实import是一种赋值操作,它将整个模块对象赋值给一个名字为模块名的变量。

注意,模块在被导入的时候,其代码是会被执行一遍的。因此,作为模块的文件,不应包含控制流程,只定义变量、函数或类即可。

“首次”被import时,会执行三个步骤:

  1. 搜索模块文件:在指定的路径下搜索模块文件。搜索顺序为:程序当前目录>PYTHONPATH目录(若设置了该变量的话)>标准链接库目录>任何.pth文件的内容(如果存在的话)。sys.path列表中列出了Python会依次查找的路径。模块必须存在于sys.path的某个路径中,才可能被搜索到。如果需要的话,可以向sys.path中append指定的路径。

  2. 编译成字节码:文件被导入时就会编译,被导入的文件会留下.pyc文件。

  3. 执行代码:依次执行被导入模块中的代码。代码执行完后,模块中定义的对象就被创建出来了,模块对象的属性和方法也随即产生。

注意:一个模块只有在首次被导入时才会执行上述三步。以后若重复导入,将只是从内存中提取该模块对象,没必要从头执行完整步骤。若非要重复执行,则需要使用reload(module)函数。

8.2. 包

不是随便一个目录放几个.py文件就可以被用作Python包。包的每个目录(至少是import路径中的目录)下必须有一个名为”__init__.py”的文件。该文件通常为空(它是一个“标识”,无需包含任何代码,但是必须要存在),充当包初始化时的“挂钩”,替目录产生模块命名空间,以及实现from * 行为。

8.3. 打包

将开发好的模块,程序打包发布。图中列出了几种发布方式:

所谓的”发布“是指一个文件集合,其具体形式可以是zip包,rpm,exe等等。Python中可使用distutils工具制作一个“发布”。制作好的发布可以用于安装,要可以上传到PyPI与他人共享。

使用distutils制作发布的流程:

  1. 将要发布的包放到一个目录下。

  2. 最好准备(非必须)一个README.txt文件。

  3. 然后,在容器中创建setup.py文件,文件内容如下:
    假设要发布的是一个名为p的Python包,其中有a.py和b.py两个模块。

    setup()中还可以设定更多参数,详见帮助文档

  4. 完成第三步后,就可以进行打包了。不指定打包格式,默认执行源码打包,即会得到一个源码包:

    1
    python setup.py sdist
    

    可以为sdist指定包格式(zip、tar.bz2等),下面是打包成.zip源码包:

    1
    python setup.py sdist --formats zip
    


    除此之外,可以使用bdist命令制作出二进制包,包中会包含各模块对应的.pyc文件。

    1
    python setup.py bdist
    

    同样可以指定不同的包格式,如:tar,tar.gz,zip,rmp,windows平台可自解压的zip包wininst,微软安装程序msi等。命令举例如下:

    1
    python setup.py bdist_wininst
    

安装一个发布的模块,使用命令:

1
python setup.py install

第三方模块会被安装到site-packages目录。

<== index ==>