模块动态加载机制
- Advanced Python(某一期Google TechTalks的话题)上提到import指令本质是个语法糖,import sys等价于sys = import(“sys”)。解析import sys的bytecode可以看到四个指令(参数略): LOAD_CONST LOAD_CONST IMPORT_NAME STORE_NAME
IMPORT_NAME把sys模块导入并保存到栈上,STORE_NAME把这个指针当作普通对象保存在sys这个变量中。
2. IMPORT_NAME指令行为分析 将参数打包并用PyEval_CallObject()这个统一调用接口运行import方法,bltinmodule.c中的builtinimport函数包装了这个功能。help(import)显示的import方法的参数列表 import(…) import(name, globals={}, locals={}, fromlist=[], level=-1) -> module
对应于builtinimport中调用的另一层函数封装
1 2 3 | |
这个函数调用了真正干活的函数,import.c中的
1 2 3 | |
3. import_module_level函数 首先调用get_parent()得到import发生时的package对象,接下来多次调用load_next依次得到各级的包名,跟踪了下import xml.dom.minidom的行为,发现name的值依次是”dom.minidom”, “minidom”。最后根据import的形式是from … import …还是import …返回不同的处理结果。
4. import_submodule函数 load_next函数中调用这个函数进行模块的查找和载入。主要分三步:find_module, load_module, add_submodule。
5. from … import … ensure_fromlist处理了这个情况。另外对于from … import *的情况,会从module文件中读入一个all对象,从中知道module公开的符号信息。
几个以后可能用到的函数:
1 2 3 4 5 6 7 8 9 10 11 12 | |