2016-09-29 46 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__。 */