如何
super()执行?这是python3.3的代码:
typedef struct { PyObject_HEAD PyTypeObject *type; PyObject *obj; PyTypeObject *obj_type; } superobject; static PyMemberDef super_members[] = { {"__thisclass__", T_OBJECT, offsetof(superobject, type), READONLY, "the class invoking super()"}, {"__self__", T_OBJECT, offsetof(superobject, obj), READONLY, "the instance invoking super(); may be None"}, {"__self_class__", T_OBJECT, offsetof(superobject, obj_type), READONLY, "the type of the instance invoking super(); may be None"}, {0} }; static void super_dealloc(PyObject *self) { superobject *su = (superobject *)self; _PyObject_GC_UNTRACK(self); Py_XDECREF(su->obj); Py_XDECREF(su->type); Py_XDECREF(su->obj_type); Py_TYPE(self)->tp_free(self); } static PyObject * super_repr(PyObject *self) { superobject *su = (superobject *)self; if (su->obj_type) return PyUnipre_FromFormat( "<super: <class '%s'>, <%s object>>", su->type ? su->type->tp_name : "NULL", su->obj_type->tp_name); else return PyUnipre_FromFormat( "<super: <class '%s'>, NULL>", su->type ? su->type->tp_name : "NULL"); } static PyObject * super_getattro(PyObject *self, PyObject *name) { superobject *su = (superobject *)self; int skip = su->obj_type == NULL; if (!skip) { skip = (PyUnipre_Check(name) && PyUnipre_GET_LENGTH(name) == 9 && PyUnipre_CompareWithASCIIString(name, "__class__") == 0); } if (!skip) { PyObject *mro, *res, *tmp, *dict; PyTypeObject *starttype; descrgetfunc f; Py_ssize_t i, n; starttype = su->obj_type; mro = starttype->tp_mro; if (mro == NULL) n = 0; else { assert(PyTuple_Check(mro)); n = PyTuple_GET_SIZE(mro); } for (i = 0; i < n; i++) { if ((PyObject *)(su->type) == PyTuple_GET_ITEM(mro, i)) break; } i++; res = NULL; Py_INCREF(mro); for (; i < n; i++) { tmp = PyTuple_GET_ITEM(mro, i); if (PyType_Check(tmp)) dict = ((PyTypeObject *)tmp)->tp_dict; else continue; res = PyDict_GetItem(dict, name); if (res != NULL) { Py_INCREF(res); f = Py_TYPE(res)->tp_descr_get; if (f != NULL) { tmp = f(res, (su->obj == (PyObject *) su->obj_type ? (PyObject *)NULL : su->obj), (PyObject *)starttype); Py_DECREF(res); res = tmp; } Py_DECREF(mro); return res; } } Py_DECREF(mro); } return PyObject_GenericGetAttr(self, name); } static PyTypeObject * supercheck(PyTypeObject *type, PyObject *obj) { if (PyType_Check(obj) && PyType_IsSubtype((PyTypeObject *)obj, type)) { Py_INCREF(obj); return (PyTypeObject *)obj; } if (PyType_IsSubtype(Py_TYPE(obj), type)) { Py_INCREF(Py_TYPE(obj)); return Py_TYPE(obj); } else { PyObject *class_attr; class_attr = _PyObject_GetAttrId(obj, &PyId___class__); if (class_attr != NULL && PyType_Check(class_attr) && (PyTypeObject *)class_attr != Py_TYPE(obj)) { int ok = PyType_IsSubtype( (PyTypeObject *)class_attr, type); if (ok) return (PyTypeObject *)class_attr; } if (class_attr == NULL) PyErr_Clear(); else Py_DECREF(class_attr); } PyErr_SetString(PyExc_TypeError, "super(type, obj): " "obj must be an instance or subtype of type"); return NULL; } static PyObject * super_descr_get(PyObject *self, PyObject *obj, PyObject *type) { superobject *su = (superobject *)self; superobject *newobj; if (obj == NULL || obj == Py_None || su->obj != NULL) { Py_INCREF(self); return self; } if (Py_TYPE(su) != &PySuper_Type) return PyObject_CallFunctionObjArgs((PyObject *)Py_TYPE(su), su->type, obj, NULL); else { PyTypeObject *obj_type = supercheck(su->type, obj); if (obj_type == NULL) return NULL; newobj = (superobject *)PySuper_Type.tp_new(&PySuper_Type, NULL, NULL); if (newobj == NULL) return NULL; Py_INCREF(su->type); Py_INCREF(obj); newobj->type = su->type; newobj->obj = obj; newobj->obj_type = obj_type; return (PyObject *)newobj; } } static int super_init(PyObject *self, PyObject *args, PyObject *kwds) { superobject *su = (superobject *)self; PyTypeObject *type = NULL; PyObject *obj = NULL; PyTypeObject *obj_type = NULL; if (!_PyArg_NoKeywords("super", kwds)) return -1; if (!PyArg_ParseTuple(args, "|O!O:super", &PyType_Type, &type, &obj)) return -1; if (type == NULL) { PyframeObject *f = PyThreadState_GET()->frame; PyCodeObject *co = f->f_pre; Py_ssize_t i, n; if (co == NULL) { PyErr_SetString(PyExc_SystemError, "super(): no pre object"); return -1; } if (co->co_argcount == 0) { PyErr_SetString(PyExc_SystemError, "super(): no arguments"); return -1; } obj = f->f_localsplus[0]; if (obj == NULL) { PyErr_SetString(PyExc_SystemError, "super(): arg[0] deleted"); return -1; } if (co->co_freevars == NULL) n = 0; else { assert(PyTuple_Check(co->co_freevars)); n = PyTuple_GET_SIZE(co->co_freevars); } for (i = 0; i < n; i++) { PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); assert(PyUnipre_Check(name)); if (!PyUnipre_CompareWithASCIIString(name, "__class__")) { Py_ssize_t index = co->co_nlocals + PyTuple_GET_SIZE(co->co_cellvars) + i; PyObject *cell = f->f_localsplus[index]; if (cell == NULL || !PyCell_Check(cell)) { PyErr_SetString(PyExc_SystemError, "super(): bad __class__ cell"); return -1; } type = (PyTypeObject *) PyCell_GET(cell); if (type == NULL) { PyErr_SetString(PyExc_SystemError, "super(): empty __class__ cell"); return -1; } if (!PyType_Check(type)) { PyErr_Format(PyExc_SystemError, "super(): __class__ is not a type (%s)", Py_TYPE(type)->tp_name); return -1; } break; } } if (type == NULL) { PyErr_SetString(PyExc_SystemError, "super(): __class__ cell not found"); return -1; } } if (obj == Py_None) obj = NULL; if (obj != NULL) { obj_type = supercheck(type, obj); if (obj_type == NULL) return -1; Py_INCREF(obj); } Py_INCREF(type); su->type = type; su->obj = obj; su->obj_type = obj_type; return 0; } PyDoc_STRVAR(super_doc, "super() -> same as super(__class__, <first argument>)n" "super(type) -> unbound super objectn" "super(type, obj) -> bound super object; requires isinstance(obj, type)n" "super(type, type2) -> bound super object; requires issubclass(type2, type)n" "Typical use to call a cooperative superclass method:n" "class C(B):n" " def meth(self, arg):n" " super().meth(arg)n" "This works for class methods too:n" "class C(B):n" " @classmethodn" " def cmeth(cls, arg):n" " super().cmeth(arg)n"); static int super_traverse(PyObject *self, visitproc visit, void *arg) { superobject *su = (superobject *)self; Py_VISIT(su->obj); Py_VISIT(su->type); Py_VISIT(su->obj_type); return 0; } PyTypeObject PySuper_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "super", sizeof(superobject), 0, super_dealloc, 0, 0, 0, 0, super_repr, 0, 0, 0, 0, 0, 0, super_getattro, 0, 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_baseTYPE, super_doc, super_traverse, 0, 0, 0, 0, 0, 0, super_members, 0, 0, 0, super_descr_get, 0, 0, super_init, PyType_GenericAlloc, PyType_GenericNew, PyObject_GC_Del, };您可以在某处看到
super_init检查
type ==NULL,然后它引发您看到的错误。
NULL周围不正常,因此其中可能存在一个错误
super(并且请注意,
super先前版本中已经存在错误)。至少我认为
SystemError应该仅在解释器或其他C代码的某些“内部”失败而不是python代码引起的情况下触发引发这种情况的情况。
另外,这不仅发生在您身上,您还可以在其中找到将此行为视为错误的帖子。



