Python 2.7如果未定义__ne__,则进行比较

时间:2016-09-29 15:15:09

标签: python-2.7

在Python中有一个名为__ne__的魔术方法,它在对象!=比较时触发。

示例:

class A(object):
    def __init__(self, a):
        self.a = a

    def __ne__(self, other):
        return self.a != other.a

A(3) != A(3) # produces False
A(3) != A(2) # produces True

问题:

如果未定义__ne__,会发生什么?

注意:在python 3.x !=中,比较被定义为反转__eq__返回的任何内容。

我认为比较对象id,在这种情况下,假设我们没有单例,所有!=比较都必须返回True。但显然在不同环境下相同的代码产生了不同的结果,所以我猜,还有其他东西被比较而不是对象ID。

2 个答案:

答案 0 :(得分:1)

如果您不在类定义中使用明确的__ne__,则会使用来自继承的__ne__的{​​{1}}。它的工作方式类似于以下代码(当然原文是用C语言编写的):

object

因为您正在比较用户定义的类,所以正在使用def __ne__(self, other): eq_result = self == other if eq_result is NotImplemented: return NotImplemented else: return not eq_result

以下是源代码source code。看看id

答案 1 :(得分:0)

turkus的回答是正确的:如果没有指定__ne__()方法,则返回__eq__()方法结果的倒数。 CPython源代码的相关部分是slot_tp_richcompare()

static PyObject *
slot_tp_richcompare(PyObject *self, PyObject *other, int op)
{
    PyObject *res;

    if (Py_TYPE(self)->tp_richcompare == slot_tp_richcompare) {
        res = half_richcompare(self, other, op);
        if (res != Py_NotImplemented)
            return res;
        Py_DECREF(res);
    }
    if (Py_TYPE(other)->tp_richcompare == slot_tp_richcompare) {
        res = half_richcompare(other, self, _Py_SwappedOp[op]);
        if (res != Py_NotImplemented) {
            return res;
        }
        Py_DECREF(res);
    }
    Py_INCREF(Py_NotImplemented);
    return Py_NotImplemented;
}

如果未定义__ne__(),则调用相反的方法(在_Py_SwappedOp[op]中定义为Py_EQ,即__eq__()Py_NE)。 classobject.c中的评论显示了__eq__()未定义时会发生什么:

  

/ *如果没有__eq__且没有__cmp__方法,我们就会哈希         地址。如果存在__eq____cmp__方法,则必须存在         是__hash__。 * /