# Python 中的层次结构对象
# 基本概念
在 Python 中,只有一种聚合的层次结构对象的概念,称为包 (Package). 包中的唯一对象类型是模块 (Module),无论模块是用 Python、C 还是其他语言实现的。包结构式层次组织的,因此其可能包含子包 (subpackage). 一个包的导入过程包括搜索和加载两个步骤。
下面是一个直白一点的概念划分:
- 库 (library): 这个概念并非 Python 里的概念,是从 C 语言过来的。库这个概念其实就是一堆代码一起完成一个或多个任务。非常类似函数,但是是以文件组织在一起。因此在 Python 中很少提及这一词汇。
- 包 (package): 包含多个模块的 “目录” 为包 package,通俗来说包就是一类功能模块的组织者。
- 模块 (module): 这个概念就是 Python 里的概念,一个模块就是一个 py 文件,然后包含多行代码执行一个或多个任务,库约等于模块。
# 包的分类
Python 中的包可以划分成两类:常规包 (regular package) 和命名空间包 (namespace package).
常规包是一个包含文件的目录,其必须包含一个初始化文件 __init__.py
, 哪怕这个文件是一个空文件。每当导入常规包时,常规包的 __init__.py
文件就会被执行。
命名空间包是一个包含 __path__
属性的目录,其 __path__
属性是一个列表,列表中的元素是包的子包的路径。命名空间包的 __init__.py
文件可以不存在,也可以是一个空文件。命名空间包的子包可以是常规包,也可以是命名空间包。命名空间包可以减少大量位于不同子目录下包的引用带来的麻烦。
# 搜索
包导入的搜索过程具有一个固定的次序规则。导入过程由错误 ModuleNotFoundError
驱动。
# 模块缓存
搜索过程首先对缓存的模块进行搜索,即对 sys.modules
搜索。 sys.modules
是一个字典,其键是模块名,值是模块对象。如果模块名在 sys.modules
中,则直接返回对应的模块对象。否则,搜索过程继续。
# 查找器和加载器
如果在 sys.modules
中没有找到对应的模块名,则
# Ref:
- Python 库、包、模块
- Python 3.x | 史上最详解的 导入(import)
- import 系统 - Python 文档
- PEP 302 – New Import Hooks
- 详解 python 常规包与命名空间包
- python 中的包 这个写的挺仔细的