2016-09-29 3 views
1

__ne__と呼ばれる魔法のメソッドが、Pythonでオブジェクト!=の比較でトリガーされます。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__が使用されます。あなたは、ユーザー定義のクラスを比較しているので、その後、idが使用されているので、

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

:それは(もちろん、元はCで書かれている)のコードを以下のように動作します。

ここにソースコード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_NEため、すなわち__eq__()Py_EQとして_Py_SwappedOp[op]で定義された)反対メソッドが呼び出されます。 classobject.c内のコメントは、何が起こるかを示してい__eq__()に定義すべきではありません。

/*何__cmp__方法がそこには__eq__がないとした場合、我々は アドレスにハッシュ。 __eq__または__cmp__メソッドが存在する場合は、 が__hash__である必要があります。 */

関連する問題