当前位置:编程学习 > 网站相关 >>

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*, 构造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

简单来说就是通过循环把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)

 

补充:Web开发 , Python ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,