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*, 构造PyModuleObject
typedef 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 = ml
v->m_self = m /*PyModuleObject* */
v->m_module = n
这个字典的key是char*字符串, value是PyCFunctionObject*
简单来说就是通过循环把methoddef的相关信息加入md_dict
typedef 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)