Python源码学习(四)-builtins模块的初始化
Module的初始化是从系统预定义的PyModuleDef开始的typedef struct PyModuleDef{ PyModuleDef_Base m_base; const char* m_name; const char* m_doc; Py_ssize_t m_size; PyMethodDef *m_methods; inquiry m_reload; traverseproc m_traverse; inquiry m_clear; freefunc m_free;}PyModuleDef;其中包含了PyMethodDef^struct PyMethodDef { const char*ml_name;/* The name of the built-in function/method */ PyCFunction ml_meth;/* The C function that implements it */ int ml_flags;/* Combination of METH_xxx flags, which mostly describe the args expected by the C func */ const char*ml_doc;/* The __doc__ attribute, or NULL */};typedef struct PyMethodDef PyMethodDef;例如对于builtins模块,相对的PyModuleDef就是static struct PyModuleDef builtinsmodule = { PyModuleDef_HEAD_INIT, "builtins", builtin_doc, -1, /* multiple "initialization" just copies the module dict. */ builtin_methods, NULL, NULL, NULL, NULL};其中builtin_methods就是static PyMethodDef builtin_methods[] = { {"__build_class__", (PyCFunction)builtin___build_class__, METH_VARARGS | METH_KEYWORDS, build_class_doc}, {"__import__", (PyCFunction)builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc}, {"abs", builtin_abs, METH_O, abs_doc}, {"all", builtin_all, METH_O, all_doc}, {"any", builtin_any, METH_O, any_doc},.....}Python启动过程中PyObject * _PyBuiltin_Init(void){ PyObject *mod, *dict, *debug; mod = PyModule_Create(&builtinsmodule);...}传入PyModuleDef*, 构造PyModuleObjecttypedef struct { PyObject_HEAD PyObject *md_dict; struct PyModuleDef *md_def; void *md_state;} PyModuleObject;PyModule里面有一个md_dict, 在每次PyObject * PyModule_New(const char *name)的调用中,md_dict都会加入 __name__, __doc__, __package__三个key接着 d = PyModule_GetDict((PyObject*)m); n = PyUnicode_FromString(name); for (ml = module->m_methods; ml->ml_name != NULL; ml++) { v = PyCFunction_NewEx(ml, (PyObject*)m, n); if (PyDict_SetItemString(d, ml->ml_name, v) != 0) ...}这里d就是上面的md_dict, v是构造出来的PyCFunctionObject*, 其中v->m_ml = mlv->m_self = m /*PyModuleObject* */v->m_module = n简单来说就是通过循环把methoddef的相关信息加入md_dicttypedef struct { PyObject_HEAD PyMethodDef *m_ml; /* Description of the C function to call */ PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */ PyObject *m_module; /* The __module__ attribute, can be anything */} PyCFunctionObject;接着是通过宏定义把一些内置type加入md_dict#define SETBUILTIN(NAME, OBJECT) \ if (PyDict_SetItemString(dict, NAME, (PyObject *)OBJECT) < 0) \ return NULL; \ ADD_TO_ALL(OBJECT) SETBUILTIN("classmethod", &PyClassMethod_Type); SETBUILTIN("complex", &PyComplex_Type); SETBUILTIN("dict", &PyDict_Type); SETBUILTIN("enumerate", &PyEnum_Type); SETBUILTIN("filter", &PyFilter_Type); SETBUILTIN("float", &PyFloat_Type); SETBUILTIN("frozenset", &PyFrozenSet_Type);bdict = PyModule_GetDict(bltinmod);#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \ if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \ Py_FatalError("Module dictionary insertion problem.");POST_INIT(BaseException) POST_INIT(Exception) POST_INIT(TypeError) POST_INIT(StopIteration) POST_INIT(GeneratorExit) POST_INIT(SystemExit) POST_INIT(KeyboardInterrupt) POST_INIT(ImportError) POST_INIT(EnvironmentError)