1

Daily Notes on Python[11.17-11.23]

 2 years ago
source link: https://blog.yxwang.me/2008/11/daily-notes-on-python1117-1123/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Daily Notes on Python[11.17-11.23]

Mon, Nov 17, 2008 • Programming

模块动态加载机制

  1. 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中的builtin__import__函数包装了这个功能。help(import)显示的__import__方法的参数列表 import(…) import(name, globals={}, locals={}, fromlist=[], level=-1) -> module

对应于builtin__import__中调用的另一层函数封装

PyObject *
PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
PyObject *fromlist, int level)

这个函数调用了真正干活的函数,import.c中的

static PyObject *
import_module_level(char *name, PyObject *globals, PyObject *locals,
PyObject *fromlist, int level)

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公开的符号信息。

几个以后可能用到的函数:

[import.c]
/* Parse a source file and return the corresponding code object */
static PyCodeObject * parse_source_module(const char *pathname, FILE *fp);

/* Execute a code object in a module and return the module object
 * WITH INCREMENTED REFERENCE COUNT.  If an error occurs, name is
 * removed from sys.modules, to avoid leaving damaged module objects
 * in sys.modules.  The caller may wish to restore the original
 * module object (if any) in this case; PyImport_ReloadModule is an
 * example.
 */
PyObject * PyImport_ExecCodeModule(char *name, PyObject *co);



About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK