栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Cpython学习笔记(2)——富比较

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

Cpython学习笔记(2)——富比较

环境

        Windows 10

        Cpython 3.7.12

概述

        Python中的富比较可以比较一个对象的两个不同实例,本片笔记主要讲述了在 object.c 中有关富比较的函数。

do_richcompare

        _Py_SwappedOp[] 就是定义的操作符集,Py_GT、Py_GE、Py_EQ、Py_NE、Py_LT、 Py_LE分别对应 <、<=、==、!=、>、>= 。

        richcmpfunc 定义在 object.h ,简单来说就是每个类型都需要实现或者指空的一个指针。

        第一个判断先判断类型不同的 v 与 w,w 的类型是否为 v 类型的子类型,再判断 w 的类型中是否规定了富比较。若上述判断都为真,则置 checked_reverse_op 为 1 ,然后将新分配的 richcmpfunc(相当于 w.操作符v )分配给对象 res ,如果 res 是已实现的,则函数返回对象 res 并减少 res 引用计数。

        第二个判断如果 v 的类型规定了富比较,那么将新分配的 richcmpfunc(相当于 v.操作符w )分配给对象 res ,如果 res 是已实现的,则函数返回对象 res 并减少 res 引用计数。

        第三个判断如果 checked_reverse_op 此时仍为 0 且 w 的类型规定了富比较,则将 w 规定的富比较赋给 richcmpfunc 类型的 f ,再将然后将新分配的 richcmpfunc(相当于 w.操作符v )分配给对象 res ,如果 res 是已实现的,则函数返回对象 res 并减少 res 引用计数。

        如果上述判断中都未返回值则进行一个 switch 判断,这个判断主要的作用是如果 v 和 w 的类型都未规定富比较,那么至少要给 == 或 != 一个合适的默认值,如果未给出则报错并返回空值,若给出则返回对象 res 并增加 res 引用计数。

int _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE};

static const char * const opstrings[] = {"<", "<=", "==", "!=", ">", ">="};

static PyObject *
do_richcompare(PyObject *v, PyObject *w, int op)
{
    richcmpfunc f;
    PyObject *res;
    int checked_reverse_op = 0;

    if (v->ob_type != w->ob_type &&
        PyType_IsSubtype(w->ob_type, v->ob_type) &&
        (f = w->ob_type->tp_richcompare) != NULL) {
        checked_reverse_op = 1;
        res = (*f)(w, v, _Py_SwappedOp[op]);
        if (res != Py_NotImplemented)
            return res;
        Py_DECREF(res);
    }
    if ((f = v->ob_type->tp_richcompare) != NULL) {
        res = (*f)(v, w, op);
        if (res != Py_NotImplemented)
            return res;
        Py_DECREF(res);
    }
    if (!checked_reverse_op && (f = w->ob_type->tp_richcompare) != NULL) {
        res = (*f)(w, v, _Py_SwappedOp[op]);
        if (res != Py_NotImplemented)
            return res;
        Py_DECREF(res);
    }
    switch (op) {
    case Py_EQ:
        res = (v == w) ? Py_True : Py_False;
        break;
    case Py_NE:
        res = (v != w) ? Py_True : Py_False;
        break;
    default:
        PyErr_Format(PyExc_TypeError,
                     "'%s' not supported between instances of '%.100s' and '%.100s'",
                     opstrings[op],
                     v->ob_type->tp_name,
                     w->ob_type->tp_name);
        return NULL;
    }
    Py_INCREF(res);
    return res;
}
 PyObject_RichCompare

        这个函数就是进行进一步的判断与断言,再调用 do_richcompare 函数。先来一个断言,若操作符 op 不在规定的操作符集中则终止程序,然后判断 v 和 w 有没有为空的,有则报错并返回空值,接着再判断是否正在进行 v 与 w 的富比较,是则返回空值。经过上述操作,再调用 do_richcompare 函数并将其返回值赋给对象 res,然后返回 res( Py_LeaveRecursiveCall 是用来结束 Py_EnterRecursiveCall 异常处理的)

PyObject *
PyObject_RichCompare(PyObject *v, PyObject *w, int op)
{
    PyObject *res;

    assert(Py_LT <= op && op <= Py_GE);
    if (v == NULL || w == NULL) {
        if (!PyErr_Occurred())
            PyErr_BadInternalCall();
        return NULL;
    }
    if (Py_EnterRecursiveCall(" in comparison"))
        return NULL;
    res = do_richcompare(v, w, op);
    Py_LeaveRecursiveCall();
    return res;
}

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

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

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