一、模块的构建
模块的构建原则:如何编写好一个.py文件
1、 功能闭包:单一.py文件实现单一且完整的功能。功能定义要清晰、设计要合理(松耦合vs紧耦合)
2、 抽象适度:用函数或类进行抽象,结合功能选择合适的抽象。采用类或函数,尽量选择一种
3、 操作闭包:模块无顶层可执行语句,导入时无输出。采用__name__、无全局可执行语句、尽量无全局变量。
二、包的构建之常规包
包有两种:常规包和命名空间包
常规包:Regular Packages,通过__init__.py对文件和目录组织形成包
命名空间包:Namespace Packages,由更分散子包组成的包。子包的位置可以在文件系统中不连续;子包可以是压缩文件或网络连接或其他系统资源。
常规包:
连续目录空间表达的、有层次的命名空间;
每个目录中包含一个__init__.py文件,可以是空文件;
当包/子包被导入时,对应目录的__init__.py文件将被执行。
同时每个包仅被导入一次,且包导入按照层次结构进行。
注意用import导入只能导入模块,不能是包。
如果使用使用from …(包)… import * 导入模块是错的。如果从模块中import 函数没有问题,因为模块已经确定了,而从包中import*时,包只是一个目录,不解释目录中有什么内容,是很难所有文件遍历的,python不提供遍历文件的方式。
可以使用__all__属性进行from…import * 方式导入:from…import * 形式需要在__init__.py文件中增加__all__属性赋值;__all__需要被赋值为列表对象,包含当前包下所有希望被导入的模块名称;__all__用来辅助导入模块,但不能辅助导入列表。
模块和包不同,模块提供功能,包提供命名空间。
三、包的构建之命名空间包
命名空间包:表达命名空间层次结构的一种逻辑包形式:
a、命名空间中各部分可以在不同的文件系统位置
b、命名空间中各子包并不包含__init__.py文件(普通目录)
c、python解释器通过sys.path变量来隐式维护命名空间包
例子:
import sys
sys.path += [‘project1’,’project2’]
import pkg1.m1
import pkg1.m3
pkg1.m1.mecho(123)
pkg.m3.mecho(‘python’)
print(pkg1.__path__)
sys.path:指定搜索路径的字符串列表
指定import时搜索模块或包的路径列表,路径是相对或绝对路径。sys.path是一个列表类型,可以用sys.path.append§增加新路径p。
载入后,根据其中包的名称和层次结构自然组成了命名空间包。
__path__属性:
记录了某个包(命名空间)的绝对或相对路径,列表类型。常规包:路径是单一的,列表中只有一个元素。命名空间包:路径是多元的,列表中可能有多个元素。