Python 只有一种模块对象类型,所有模块都属于该类型,无论模块是用 Python、C 还是别的语言实现。为了帮忙组织模块并提供名称层次结构,Python 还引入了包的概念。
你能够把包看成是文件系统中的目录,并把模块看成是目录中的文件,但请不要对这个类比做过于字面的了解,因为包和模块不是必须来自于文件系统。为了不便了解本文档,咱们将持续应用这种目录和文件的类比。与文件系统一样,包通过层次结构进行组织,在包之内除了个别的模块,还能够有子包。
要留神的一个重点概念是所有包都是模块,但并非所有模块都是包。或者换句话说,包只是一种非凡的模块。特地地,任何具备 __path__ 属性的模块都会被当作是包。All modules have a name. Subpackage names are separated from their parent package name by a dot, akin to Python’s standard attribute access syntax. Thus you might have a package called email, which in turn has a subpackage called email.mime and a module within that subpackage called email.mime.text.
5.2.1. 惯例包
Python 定义了两种类型的包,惯例包 和 命名空间包。惯例包是传统的包类型,它们在 Python 3.2 及之前就已存在。惯例包通常以一个蕴含 __init__.py 文件的目录模式实现。当一个惯例包被导入时,这个 __init__.py 文件会隐式地被执行,它所定义的对象会被绑定到该包命名空间中的名称。__init__.py 文件能够蕴含与任何其余模块中所蕴含的 Python 代码类似的代码,Python 将在模块被导入时为其增加额定的属性。例如,以下文件系统布局定义了一个最高层级的 parent 包和三个子包:
parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
导入 parent.one 将隐式地执行 parent/__init__.py 和 parent/one/__init__.py。后续导入 parent.two 或 parent.three 则将别离执行 parent/two/__init__.py 和 parent/three/__init__.py。
5.2.2. 命名空间包
命名空间包是由多个 局部 形成的,每个局部为父包减少一个子包。各个局部可能处于文件系统的不同地位。局部也可能处于 zip 文件中、网络上,或者 Python 在导入期间能够搜寻的其余中央。命名空间包并不一定会间接对应到文件系统中的对象;它们有可能是无实体示意的虚构模块。
命名空间包的 __path__ 属性不应用一般的列表。而是应用定制的可迭代类型,如果其父包的门路 (或者最高层级包的 sys.path) 产生扭转,这种对象会在该包内的下一次导入尝试时主动执行新的对包局部的搜寻。命名空间包没有 parent/__init__.py 文件。实际上,在导入搜寻期间可能找到多个 parent 目录,每个都由不同的局部所提供。因而 parent/one 的物理地位不肯定与 parent/two 相邻。在这种状况下,Python 将为顶级的 parent 包创立一个命名空间包,无论是它自身还是它的某个子包被导入。
以上就是本次分享的全部内容,当初想要学习编程的小伙伴欢送关注 Python 技术大本营,获取更多技能与教程。