现在的位置: 主页 > 公司荣誉 > 文章正文

Python源码学习之初始化(二)

作者:陕西芙爱尔婚庆礼仪服务有限公司 来源:www.fair521.com 未知发布时间:2017-09-13 12:50:55
Python源码学习之初始化(二) 在初始化中,调用 void _Py_ReadyTypes(void) if (PyType_Ready(&PyType_Type) < 0) Py_FatalError("Can't initialize type type"); if (PyType_Ready(&_PyWeakref_RefType) < 0) Py_FatalError("Can't initialize weakref type"); ... 对各种数据类型的定义做初始化 来看 int PyType_Ready(PyTypeObject *type)的定义, 它把传入的type的tp_base用&PyBaseObject_Type初始化 ... /* Initialize tp_base (defaults to BaseObject unless that's us) */ base = type->tp_base; if (base == NULL && type != &PyBaseObject_Type) base = type->tp_base = &PyBaseObject_Type; Py_INCREF(base); /* Now the only way base can still be NULL is if type is * &PyBaseObject_Type. */ /* Initialize the base class */ if (base != NULL && base->tp_dict == NULL) if (PyType_Ready(base) < 0) //有点递归的意思 goto error; ... 接着初始化其他成员变量 /* Initialize tp_bases */ bases = type->tp_bases; if (bases == NULL) if (base == NULL) bases = PyTuple_New(0); else bases = PyTuple_Pack(1, base); if (bases == NULL) goto error; type->tp_bases = bases; /* Initialize tp_dict */ dict = type->tp_dict; if (dict == NULL) dict = PyDict_New(); if (dict == NULL) goto error; type->tp_dict = dict; 接着是一些内置function的初始化 /* Add type-specific descriptors to tp_dict */ if (add_operators(type) < 0) goto error; if (type->tp_methods != NULL) if (add_methods(type, type->tp_methods) < 0) goto error; if (type->tp_members != NULL) if (add_members(type, type->tp_members) < 0) goto error; 这里重点看一下add_operators in typeobject.c static int add_operators(PyTypeObject *type) ... init_slotdefs(); ... /* Initialize the slotdefs table by adding interned string objects for the names and sorting the entries. */ static void init_slotdefs(void) { slotdef *p; static int initialized = 0; if (initialized) return; for (p = slotdefs; p->name; p++) p->name_strobj = PyUnicode_InternFromString(p->name); if (!p->name_strobj) Py_FatalError("Out of memory interning slotdef names"); qsort((void *)slotdefs, (size_t)(p-slotdefs), sizeof(slotdef), slotdef_cmp); initialized = 1; } //这里是我们在python编程中经常重载的一些函数的列表 static slotdef slotdefs[] = SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, "x.__len__() <==> len(x)"), SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, "x.__add__(y) <==> x+y"), SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, "x.__getitem__(y) <==> x[y]"), ... SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, "x.__len__() <==> len(x)") #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER, DOC) 等价 ETSLOT("__len__", as_sequence.sq_length, slot_sq_length, wrap_lenfunc, "x.__len__() <==> len(x)") #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ PyDoc_STR(DOC) 等价 "__len__", offsetof(PyHeapTypeObject, as_sequence.sq_length), (void*)slot_sq_length, wrap_lenfunc, PyDoc_STR("x.__len__() <==> len(x)") 而 typedef struct wrapperbase slotdef; struct wrapperbase char *name; int offset; void *function; wrapperfunc wrapper; char *doc; int flags; PyObject *name_strobj;; 于是上面的宏定义展开为 "__len__", /* name */ offsetof(PyHeapTypeObject, /* offset* / as_sequence.sq_length), (void*)slot_sq_length, /* void *function */ wrap_lenfunc, /* wrapper */ PyDoc_STR("x.__len__() <==> len(x)") /* char *doc */ 新建一个module的时候,总会调用,而 PyDict_SetItemString(m->md_dict, "__name__", nameobj) 这个函数会向字典里面加一个item, 于是我们可以在python启动以后写 xxxx.__name__, xxx.__doc__ PyObject * PyModule_New(const char *name) nameobj == NULL) goto fail; if (PyDict_SetItemString(m->md_dict, "__name__", nameobj) != 0) goto fail; if (PyDict_SetItemString(m->md_dict, "__doc__", Py_None) != 0) goto fail; if (PyDict_SetItemString(m->md_dict, "__package__", Py_None) != 0) goto fail; Py_DECREF(nameobj); PyObject_GC_Track(m); return (PyObject *)m; fail: Py_XDECREF(nameobj); Py_DECREF(m); return NULL; 当我们在命令行输入任何command的时候,都会调用pythonrun.c int PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)


在PyTypeObject初始化中,add_xxxx 是操作该object的tp_dict,把每一个operator, method,member定义都以key-value的形势放到tp_dict里面 <span style="white-space:pre"> </span>if (add_operators(type) < 0) &nbsp; &nbsp; &nbsp; &nbsp; goto error; &nbsp; &nbsp; if (type->tp_methods != NULL) &nbsp; &nbsp; &nbsp; &nbsp; if (add_methods(type, type->tp_methods) < 0) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto error; &nbsp; &nbsp; &nbsp; &nbsp; if (type->tp_members != NULL) &nbsp; &nbsp; &nbsp; &nbsp; if (add_members(type, type->tp_members) < 0) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto error; &nbsp; &nbsp; &nbsp; &nbsp; if (type->tp_getset != NULL) &nbsp; &nbsp; &nbsp; &nbsp; if (add_getset(type, type->tp_getset) < 0) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto error; &nbsp; &nbsp;

,站群软件,站群软件

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:武汉做网站 https://www.feimao666.com

上一篇:关于Python中的类普通继承与super函数继承 下一篇:最后一页