Python 模块加载

本文主要介绍Python模块加载的过程。

module的组成

module都是由对象和对象之间的关系组成。

type VS object

Python中所有的东西都是对象,可划分为三类:

  • 类型type
  • 类class
  • 实例instance

三种对象之间的两种关系:

  • is kind of,基类和子类的关系
  • is instance of,类和对象的关系

类和对象的关系可以通过内建方法type来辨别。

Python中,任何一个类都是直接或间接继承自object,而每一个对象都会拥有自己的type类型,可以通过__class__属性获得。

环境初始化

Python初始化的第一步是加载多个基础的module,例如\_\_builtin\_\_,sys等,同时也会完成Python类型系统的初始化和异常系统的初始化。

模块初始化

Python内部维护了一个加载到内存的module集合,用于查找module是否存在。

如果存在直接返回该module对象,否则创建该module对象,并插入到module集合中。创建module后,需要设置module的属性。

为了避免再一次初始化同样的module,Python将所有的扩展module通过一个全局的PyDictObject对象来进行备份维护。

Update 2019/11/28
类似Java的双亲委派模型。

Python的module集合是一个PyDictObject对象,而PyDictObject对象是一个全局变量。

启动虚拟机

Python包括两种运行方式:命令行脚本文件

Python中的run_mode函数基于AST抽象语法树 (AST, Abstract Syntax Tree)完成了字节码的编译工作,并创建PyCodeObject对象

Python中所有的线程都是共享同样的builtin命名空间

涉及到了三种命名空间:Local/Global/Builtin

动态加载

import功能包括:

  • 全局module缓存的维护和搜索;
  • 解析和搜索module路径的树形结构
  • 对不同文件格式的module动态加载机制

py文件中的import只会影响各自module自身维护的那个dict对象

import操作可能影响全局的module集合,通过判断全局module集合中是否已经缓存该module模块来决定是否加载。

module的基础之上,Python提供了package机制,文件件中存在\_\_init\_\_.py文件才能成为package(多个py文件组成的文件夹)。

逻辑相关联的module需要聚合到同一package。
通过package机制来管理module,通过module来管理class

del删除模块只是把模块从当前命名空间中删除,但该module依然存在于module缓存中。

模块缓存

Python中的全局module集合sys.modules被称为modules缓存,保证了module的唯一性,每当有import操作都会在该sys.modules查找,如果不存在就会将该module加入到sys.modules中。

如果已经加载的模块发生改变,那么需要调用reload函数来重新加载该模块。需要注意reload函数并不会重新创建该对象,而在在原有对象的基础上做修改。