为PythonC扩展类型定义_eq__
我在尝试为作为C扩展编写的Rect类实现为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 ||
\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 */