栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何在Python 3中实现super()?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何在Python 3中实现super()?

如何

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代码引起的情况下触发引发这种情况的情况。

另外,这不仅发生在您身上,您还可以在其中找到将此行为视为错误的帖子。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/455675.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号