Import模块分析 ------------------ :: >>> dis.dis(compile("import os", "", "exec")) 1 0 LOAD_CONST 0 (-1) 3 LOAD_CONST 1 (None) 6 IMPORT_NAME 0 (os) 9 STORE_NAME 0 (os) 12 LOAD_CONST 1 (None) 15 RETURN_VALUE Python/ceval.c ============== case IMPORT_NAME: w = GETITEM(names, oparg); // 取__import__这个builtin函数 x = PyDict_GetItemString(f->f_builtins, "__import__"); if (x == NULL) { PyErr_SetString(PyExc_ImportError, "__import__ not found"); break; } Py_INCREF(x); // 打包参数 v = POP(); u = TOP(); if (PyInt_AsLong(u) != -1 || PyErr_Occurred()) w = PyTuple_Pack(5, w, f->f_globals, f->f_locals == NULL ? Py_None : f->f_locals, v, u); else w = PyTuple_Pack(4, w, f->f_globals, f->f_locals == NULL ? Py_None : f->f_locals, v); Py_DECREF(v); Py_DECREF(u); if (w == NULL) { u = POP(); Py_DECREF(x); x = NULL; break; } READ_TIMESTAMP(intr0); // 调用__import__函数 // __import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module v = x; x = PyEval_CallObject(v, w); Py_DECREF(v); READ_TIMESTAMP(intr1); Py_DECREF(w); SET_TOP(x); if (x != NULL) continue; break; Python/bltinmodule.c ==================== static PyMethodDef builtin_methods[] = { {"__import__", (PyCFunction)builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc}, ... }; static PyObject * builtin___import__(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"name", "globals", "locals", "fromlist", "level", 0}; char *name; PyObject *globals = NULL; PyObject *locals = NULL; PyObject *fromlist = NULL; int level = -1; if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|OOOi:__import__", kwlist, &name, &globals, &locals, &fromlist, &level)) return NULL; // ok,import模块的入口 return PyImport_ImportModuleLevel(name, globals, locals, fromlist, level); } Python/import.c ================= PyObject * PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) { PyObject *result; _PyImport_AcquireLock(); // 好吧,这个才是最终的入口 result = import_module_level(name, globals, locals, fromlist, level); if (_PyImport_ReleaseLock() < 0) { Py_XDECREF(result); PyErr_SetString(PyExc_RuntimeError, "not holding the import lock"); return NULL; } return result; } static PyObject * import_module_level(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) { char buf[MAXPATHLEN+1]; Py_ssize_t buflen = 0; PyObject *parent, *head, *next, *tail; if (strchr(name, '/') != NULL #ifdef MS_WINDOWS || strchr(name, '\\') != NULL #endif ) { PyErr_SetString(PyExc_ImportError, "Import by filename is not supported."); return NULL; } // 获取import语句所在的package parent = get_parent(globals, buf, &buflen, level); if (parent == NULL) return NULL; head = load_next(parent, level < 0 ? Py_None : parent, &name, buf, &buflen); if (head == NULL) return NULL; tail = head; Py_INCREF(tail); while (name) { next = load_next(tail, tail, &name, buf, &buflen); Py_DECREF(tail); if (next == NULL) { Py_DECREF(head); return NULL; } tail = next; } if (tail == Py_None) { /* If tail is Py_None, both get_parent and load_next found an empty module name: someone called __import__("") or doctored faulty bytecode */ Py_DECREF(tail); Py_DECREF(head); PyErr_SetString(PyExc_ValueError, "Empty module name"); return NULL; } if (fromlist != NULL) { if (fromlist == Py_None || !PyObject_IsTrue(fromlist)) fromlist = NULL; } if (fromlist == NULL) { Py_DECREF(tail); return head; } Py_DECREF(head); if (!ensure_fromlist(tail, fromlist, buf, buflen, 0)) { Py_DECREF(tail); return NULL; } return tail; } reload一个模块会复用已经载入的该模块的md_dict。对于pure python的模块,如果要干净 的reload,可以先将该模块从sys.modules中删除。当然这个对于builtin和c module是无效 的。 :: $ cat foo.py a = 1 b = 2 print 'foo' >>> import foo foo >>> dir(foo) ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'a', 'b'] $cat foo.py a = 1 c = 2 print 'foo' >>> reload(foo) foo >>> dir(foo) ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'a', 'b', 'c'] >>> import sys >>> del sys.modules['foo'] >>> import foo foo >>> dir(foo) ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'a', 'c']