2012-11-22 53 views
3

假設我定義了一個類A,並且我不希望任何人在沒有離開的情況下編寫該類的不等式。爲什麼NotImplemented引發TypeError?

class A(): 
    def __ne__(self, other): 
     return NotImplemented 
print(A() != A()) 

但這打印出True並沒有提出一個TypeError雖然我刻意「關閉」的!=操作?

回答

8

,所以你應該有一個看起來像這樣的方法。

通常,Python會交換操作數;如果a != b結果爲NotImplemented,則會嘗試使用b != a。這也會失敗,因爲您在操作員的兩側使用相同的類型。對於!=運算符,Python將回退以比較它們的內存地址,並且它們不相同(兩個單獨的實例),因此返回False。

請參閱do_richcompare C function for details

如果這是您的預期結果,則必須手動籌集TypeError()

+0

3.x豐富的比較實現的簡單性是一個值得歡迎的解決方案。在2.x中,不是調用'__ne__'兩次,Python將其調用6次(當'PyObject_RichCompare'調用'slot_tp_richcompare'時,兩次調用'try_rich_compare'嘗試按正常順序和交換順序執行4次]。最後,它會在'default_3way_compare'中得到指針比較,因爲必須轉換爲'uintptr_t'來支持排序。 – eryksun

+0

是的,在這個問題上看到'python-3.x'標籤讓我感到很放心。不得不詳細說明在python 2中如何工作會導致*稍微*更長的答案。然而,我只按照LR,RL,RL,LR(用於左手和右手實例)的順序,對'A()!= A()'計算'__ne__'的* 4 *調用次數。 –

-2

它給你真正的,因爲你是返回一個例外,而不是它提高它。這意味着你正在返回一個非Null對象(例外)作爲測試的結果。除非另有說明,否則非空對象評估爲True。 請記住,除非您提出異常,否則這是一個普通對象。當您返回NotImplemented表明您不知道如果__ne__返回TrueFalse

class A(): 
    def __ne__(self, other): 
     raise NotImplementedError 
+2

不,它是*不是例外。閱讀['__ne__']的文檔(http://docs.python.org/3/reference/datamodel.html#object.__ne__);這是一個單身人士爲此目的。 –

+0

的確,我正在考慮這個例外。不要誤解我的意思,但是從這個意義上說文檔是有缺陷的,因爲NotImplemented的bool()返回True,並且不會給出任何有意義的錯誤。所以,正確的程序是引發一個例外,至少在OP的意圖上(據我所知) – EnricoGiampieri

+0

不,'NotImplemented'是一個非常有用的哨兵值(也就是說,一個值表示在那裏沒有實現的東西)。 – delnan

相關問題