python 模块加载

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

module的组成

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

type和object

python中所有的东西都是对象,分为三类:类型type、类class和实例instance。

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

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

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

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

运行环境初始化

python首先需要加载多个基础的module,例如__builtin__,sys等,同时也会完成python类型系统的初始化和异常系统的初始化。

系统module初始化

Python内部维护了一个维护加载到内存的module集合,需要现在集合中查找module是否存在。如果存在直接返回该module对象,否则创建该module对象,并插入到module集合中。创建module后,需要设置module的属性。

由于python的module集合是一个PyDictObject对象,而PyDictObject对象在Python中是一个可变对象,所以其中维护的元素有可能在运行时被删除。对于Python的扩展module,例如sys,为了避免再一次初始化同样的module,python将所有的扩展module通过一个全局的PyDictObject对象来进行备份维护。

启动虚拟机

python包括两种运行方式:命令行和脚本文件。

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

python中所有的线程都是共享同样的builtin名字空间。

模块的动态加载

import功能包括:

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

py文件中的import不会影响上一层的命名空间,只会影响各自的命名空间,也就是影响各自module自身维护的那个dict对象。但所有的import操作都会影响全局的module集合,这样的话只要再一次import该module,python虚拟机只需要将全局module集合中缓存的对象返回。

在module的基础之上,python提供了package机制(逻辑相关联的module需要聚合到同一package中)。也就是说通过package机制来管理module,通过module来管理class。

文件件中存在__init__.py文件才能成为package(多个py文件组成的文件夹)。

在加载package下的module时,例如a.b.c,python内部将这个module视为一个树形结构,c是b的子节点,b是a的子节点。python虚拟机在动态加载时,需要将这个树形结构分解,然后从左到右依次去sys.modules中查找每一个符号是否存在。如果已经存在,假设存在a,那么在a对应的PyModuleObject对象中保持着__path__路径信息,此时就可以在a.__path__路径中搜索b和c了。

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

module缓存

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

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

python 模块加载的更多相关文章

  1. python︱模块加载(pip安装)以及pycharm安装与报错解决方式

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 准备放下R开始学python,真是痛苦,因为找 ...

  2. python 模块加载错误总结

    在运行yum时提示如下错误 There was a problem importing one of the Python modules required to run yum. The error ...

  3. 【Python】python模块加载

    一个python文件就是一个模块 标准模块 python自带的模块就是标准模块,也就说可以直接import进来的就是标准模块 import datetime import random 第三方模块 别 ...

  4. Python学习-3.Python的模块加载

    Python中使用import关键字进行模块加载. 先在Visual Studio中建立PythonModuleLoad项目作为演示. 1.同目录加载 建立SameFolder.py文件 写入代码: ...

  5. Python 模块化 模块搜索顺序、重复导入、模块加载列表(五)

    模块搜索顺序.重复导入.模块加载列表 0x00 模块搜索顺序: 举例: #test.py import sys for p in sys.path: print(p) 运行结果: C:\python ...

  6. javascript中的闭包、模块与模块加载

    一.前言 闭包是基于词法作用域(  和动态作用域对应,词法作用域是由你写代码时,将变量写在哪里来决定的,因此当词法分析器处理代码时,会保持作用)书写代码时所产生的自然结果,甚至不需要为了利用闭包而有意 ...

  7. ECMA Script 6_模块加载方案 ES6 Module 模块语法_import_export

    1. 模块加载方案 commonJS 背景: 历史上,JavaScript 一直没有模块(module)体系, 无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来. 其他语言都有这项功能: ...

  8. 实现一个类 RequireJS 的模块加载器 (二)

    2017 新年好 ! 新年第一天对我来说真是悲伤 ,早上兴冲冲地爬起来背着书包跑去实验室,结果今天大家都休息 .回宿舍的时候发现书包湿了,原来盒子装的牛奶盖子松了,泼了一书包,电脑风扇口和USB口都进 ...

  9. node模块加载层级优化

    模块加载痛点 大家也或多或少的了解node模块的加载机制,最为粗浅的表述就是依次从当前目录向上级查询node_modules目录,若发现依赖则加载.但是随着应用规模的加大,目录层级越来越深,若是在某个 ...

随机推荐

  1. IOS 支付、性能调试、IPv6兼容支持等

    微信支付 支付宝支付 性能调试 IPv6兼容支持 APP引导页框架

  2. hibernate配置 sqlserver 数据库自动增长

    <id  name="Id" type="integer"> <column name="userid" > < ...

  3. ASP.NET使用ConfigurationSection在Web.Config创建自定义配置节集合

    核心代码 using System; using System.Data; using System.Configuration; using System.Web; using System.Web ...

  4. 注意ArrayAdapter的Add()方法

    ArrayAdapter类可以作为ListView等的适配器资源,并且可以动态向适配器中添加新的数据,这就是ArrayAdapter.Add()方法的作用.但是在使用该方法时如果出错,那就需要检查Ar ...

  5. 关于PHP堆栈与列队

    在PHP中数组常被当作堆栈(后进先出:LIFO)与队列(先进先出:FIFO)结构来使用.PHP提供了一组函数可以用于push与pop(堆栈)还有shift与unshift(队列)来操作数组元素.堆栈与 ...

  6. Ajax&json

    通过json-lib方式 复杂情况:

  7. 51NOD算法马拉松11 B君的竞技场

    传送门 这题我在比赛的时候竟然没有想出来,真是-- 这道题我们可以想一想怎么搞定获胜的概率p. 我们发现再怎么这个p都是搞不了的.所以我们可以积一下分,然后就可以不用去管p了.我们要做的就是求出一个关 ...

  8. TreeMap源码分析

    MapClassDiagram

  9. iOS之NSString类中compare方法的陷阱

    typedef NS_ENUM(NSInteger, NSComparisonResult) {NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDe ...

  10. 【C-数据类型 常量 变量】

    一.基本数据类型 1) 整型 (int   %d) 2) 字符型 (char  %c) 3) 浮点型 %f ①. 单精度浮点型(float) ②. 双精度浮点型(double) 2.指针类型 void ...