gpt4 book ai didi

python - 为 Python C 扩展类型定义 __eq__

转载 作者:太空宇宙 更新时间:2023-11-03 15:22:59 25 4
gpt4 key购买 nike

我在尝试为我作为 C 扩展编写的 Rect 类实现 __eq__ 时遇到问题。我尝试定义一个名为 __eq__ 的方法,但 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 默认为“is”行为:

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

最佳答案

在使用 C 中定义的新类型时,您需要定义 tp_richcompare。下面是一个类型的丰富比较的实现,它总是比所有其他类型(除了它自己)比较大:

static PyObject *
Largest_richcompare(PyObject *self, PyObject *other, int op)
{
PyObject *result = NULL;

if (UndefinedObject_Check(other)) {
result = Py_NotImplemented;
}
else {
switch (op) {
case Py_LT:
result = Py_False;
break;
case Py_LE:
result = (LargestObject_Check(other)) ? Py_True : Py_False;
break;
case Py_EQ:
result = (LargestObject_Check(other)) ? Py_True : Py_False;
break;
case Py_NE:
result = (LargestObject_Check(other)) ? Py_False : Py_True;
break;
case Py_GT:
result = (LargestObject_Check(other)) ? Py_False : Py_True;
break;
case Py_GE:
result = Py_True;
break;
}
}

Py_XINCREF(result);
return result;
}

如果您使用的是 Python 3.x,您可以像这样将它添加到类型对象中:

(richcmpfunc)&Largest_richcompare,       /* tp_richcompare */

如果您使用的是 Python 2.x,则需要一个额外的步骤。在 Python 2.x 的生命周期中添加了丰富的比较,对于一些 Python 版本,C 扩展可以选择定义 tp_richcomare。要通知 Python 2.x 您的类型实现了丰富的比较,您需要通过在 Py_TPFLAGS_HAVE_RICHCOMPARE 中进行 or-ing 来修改 tp_flags。

Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_RICH_COMPARE,        /* tp_flags */

关于python - 为 Python C 扩展类型定义 __eq__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12023983/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com