为PythonC扩展类型定义_eq__

为PythonC扩展类型定义_eq__,python,c,Python,C,我在尝试为作为C扩展编写的Rect类实现\uuuuueq\uuuu时遇到问题。我试着定义一个名为\uuuuuueq\uuuu的方法,但Python似乎覆盖了它 static PyObject * Rect___eq__(Rect *self, PyObject *other) { Rect *rect = (Rect *) other; if (self->x != rect->x || self->y != rect->y ||

我在尝试为作为C扩展编写的Rect类实现
\uuuuueq\uuuu
时遇到问题。我试着定义一个名为
\uuuuuueq\uuuu
的方法,但Python似乎覆盖了它

static PyObject *
Rect___eq__(Rect *self, PyObject *other)
{
    Rect *rect = (Rect *) other;
    if (self->x != rect->x || self->y != rect->y || 
            self->width != rect->width || self->height != rect->height) {
        Py_RETURN_FALSE;
    } else {
        Py_RETURN_TRUE;
    }
}

static PyMethodDef Rect_methods[] = {
    {"__eq__", (PyCFunction)Rect___eq__, METH_VARARGS,
     "Compare Rects" },
    {NULL}  /* Sentinel */
};
似乎无论我做什么,Python都默认为“是”行为:

>>> a = Rect(1, 2, 3, 4)
>>> b = Rect(1, 2, 3, 4)
>>> a == b
False
>>> a == a
True

当您声明PyTypeObject时,有一个“rich comparison”函数字段,它对应于python函数上的
\uuu cmp\uuu
(http://docs.python.org/py3k/extending/newtypes.html#object-比较)(在文档中称之为“非富”,与“富”相对。撇开语义不谈,它基本上提供了相同的功能,尽管我不太清楚为什么
\uuuuueq\uuuuu
不起作用


另一方面,我建议其他编写C扩展类/模块的人看看Cython,它确实添加了一个依赖项(尽管它只是一个构建依赖项),但编写扩展的麻烦要小得多。

在使用C中定义的新类型时,需要定义tp\u richcompare。下面是一个富比较类型的实现,该类型总是比所有其他类型(自身除外)进行比较:

如果您使用的是Python 3.x,请将其添加到类型对象中,如下所示:

(richcmpfunc)&Largest_richcompare,       /* tp_richcompare */
如果您使用的是Python2.x,那么还需要一个额外的步骤。在Python2.x的生命周期中添加了丰富的比较,对于一些Python版本,C扩展可以选择性地定义tp_richcomare。要通知Python2.x您的类型实现了丰富的比较,您需要在Py\u TPFLAGS\u HAVE\u RICHCOMPARE中修改tp\u标志

Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_RICH_COMPARE,        /* tp_flags */

我坦率地承认,我对C API了解不多,但是你看过关于C API的参考手册了吗?特别是tp_richcompare?对我来说似乎还可以,也许问题出在代码的另一部分。我当时太忙了,无法处理eq。我完全忘记了cmp。尴尬的。。。
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_RICH_COMPARE,        /* tp_flags */