2009-06-30 41 views
24

翻閱decimal.py,它在許多特殊方法中使用NotImplemented。例如Python未實現常量

class A(object): 
    def __lt__(self, a): 
     return NotImplemented 

    def __add__(self, a): 
     return NotImplemented 

Python docs say

NotImplemented

可以由「富比」 特殊方法(__eq__()__lt__(), 和朋友)返回特殊值,指示 比較沒有與 相關的其他類型實現。

它沒有談論其他特殊方法,也沒有描述行爲。

它似乎是一個神奇的物體,如果從其他特殊方法返回引發TypeError,並且在「豐富的比較」中,特殊方法什麼也不做。

例如

print A() < A() 

打印True,但

print A() + 1 

提高TypeError,所以我很好奇,這是怎麼回事,什麼是NotImplemented的使用/行爲。

+2

全部正確。你完全描述了NotImplemented。問題是什麼? – 2009-06-30 10:06:58

+0

我的問題是,如果在doc中,它特別提到了「豐富比較」的特殊方法,其他方法應該忽略它,畢竟它只是另一個對象,我找不到doc解釋一般行爲或如何處理未實現 – 2009-06-30 11:56:05

回答

26

NotImplemented允許您指示兩個給定操作數之間的比較尚未實現(而不是指示比較有效,但對於兩個操作數產生False)。

Python Language Reference

對於對象的x和y,第一x.__op__(y) 試圖。如果未執行 或返回NotImplemented,則嘗試使用 y.__rop__(x)。如果這也是 未實現或返回 NotImplemented,則會引發TypeError異常 。但看到下面的 例外:

例外以前的 項目:如果左操作數是一個內置式或 新式類,而右邊的操作數 是一個實例的 實例的 該類型或類和覆蓋 基的__rop__()方法適當子類中,右 操作數的__rop__()方法左操作數的__op__() 方法嘗試過 。這樣做是爲了使 子類可以完全覆蓋 二元運算符。否則,左 操作數的__op__()方法將總是 接受右操作數:當預期給定類的 實例, 類的子類的實例總是可以接受的。

4

它實際上有從__add____lt__返回時相同的含義,不同的是Python的2.X試圖對象放棄之前比較的其他方式。 Python 3.x確實會引發TypeError。事實上,Python可以嘗試__add__的其他東西,看看__radd__和(雖然我很模糊)__coerce__

# 2.6 
>>> class A(object): 
... def __lt__(self, other): 
...  return NotImplemented 
>>> A() < A() 
True 

# 3.1 
>>> class A(object): 
... def __lt__(self, other): 
...  return NotImplemented 
>>> A() < A() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unorderable types: A() < A() 

查看Ordering Comparisions (3.0 docs)瞭解更多信息。

0

如果從__add__返回它,它將表現爲對象沒有__add__方法,並且引發TypeError

如果您從豐富的比較函數中返回NotImplemented,則Python的行爲將類似於未實現的方法,也就是說,它將推遲使用__cmp__