2016-09-29 47 views
1

在Python中有一种称为__ne__的神奇方法,该方法在对象!=比较中触发。Python 2.7如果未定义__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

如果在类定义中不使用明确的__ne__,则将使用来自继承的object__ne__。它的工作原理就像下面的代码(当然原来是用C):

def __ne__(self, other): 
    eq_result = self == other 
    if eq_result is NotImplemented: 
     return NotImplemented 
    else: 
     return not eq_result 

所以因为你比较用户定义的类,然后被用于id

这里是源代码source code。看看slot_tp_richcompare

+0

你是从哪里拿来的?你有链接到C实现这个功能吗? – vovaminiof

+0

@vovaminiof编辑。 – turkus

1

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__。 */