1.這些比較函數都稱為rich comparison,正常情況下,它們回返回真或假。實際上這些函數都可以返回任意類型的值,如果這些比較被運用在布爾環境中的時候,比方說if 語句的條件中時,python 會調用bool()函數來確認當前的傳回值是真還是假。(劃橫線的地方不會翻譯=。=)
2.這些函數的定義之間並沒有引申的含義,比如說如果a==b是真,並不代表a!=b一定是假。所以我們在定義__eq__函數的時候也應該同時定義__ne__函數以確保我們能夠得到我們想要的結果。如果我們想瞭解可雜湊對象的比較的資訊,我們最好去看看__hash__()的文檔。這裡就不展開了,具體文章在這裡(實習小記-python中可雜湊對象是個啥?what is hashable object in python?)
3.這些函數並沒有可替換參數之說(像是左邊的參數不支援這個函數,而右邊的參數支援。)這裡要說的是,__lt__()函數和__gt__()函數他們兩個的取值是一定相反的;__le__()和__ge__()也一定是取相反的;但是__eq__()函數和__ne__()函數是各自獨立定義的。相互之間並沒有關係。這也就是2裡面提到的。
4.比較這類操作的參數是不會類型轉換的。(如果a,b做比較,a是浮點,b是整數,比較結束後b不會變成浮點類型?)
5.如果我們希望能夠在一些情況下自動排序,那麼請參考functools.total_ordering()
讀到這裡我們在回到之前的代碼中看看,到底發生了什麼
>>> class A:... def __eq__(self, other): # 不論發生什麼,只要有==做比較,就返回True... return True... >>> a = A()>>> b = A()>>> a == bTrue>>> a != b # 這個地方為什麼會返回False?False>>> a > bTraceback (most recent call last): File "<ipython-input-7-1e61210fe837>", line 1, in <module> a > bTypeError: unorderable types: A() > A()>>> x = [1,2,3,b,4,5]>>> x.index(b) # 首先拿x中的1與b做比較,應該是==的比較,由於b.__eq__()無論什麼情況下都返回True。所以python以為第一個元素就是b,於是返回index 00>>> x.index(2)1>>> x.index(4) # 這裡拿4做比較,x中的元素安順序比較,1,2,3為False,但當比較到b時由於b的坑爹屬性返回True,以為找到了,返回index 33>>> x.index(5) # 同上3>>> x.index(6) # 同上3>>> x.index(a) # 和第一次相比的原因是一樣的。0
那麼問題來了,如果我們需要一種類,該類的執行個體做比較的時候比較類中屬性,屬性相等返回True,在列表中尋找時也能正確尋找,應該如何寫呢?請看下面代碼:
>>> class A:... def __init__(self, x):... self.x = x... def __eq__(self, other):... try:... return self.x == other.x... except AttributeError:... return False... def __ne__(self, other):... try:... return self.x != other.x... except AttributeError: # 發現兩者不可比,傳回型別錯誤... raise TypeError(‘this two argument is not comparable!‘)... >>> a = A(1)>>> b = A(1)>>> c = A(2)>>> a == bTrue>>> a != bFalse>>> a == cFalse>>> a != c # 相同類型做比較,確實不相同True>>> a == 1 # 不同類型做比較,返回FalseFalse>>> a != 1 # 判斷不同類型是否不等,報類型錯誤Traceback (most recent call last): File "<ipython-input-52-30ec16ffc1a6>", line 1, in <module> a != 1 File "<ipython-input-43-70049527ba59>", line 13, in __ne__ raise TypeError(‘this two argument is not comparable!‘)TypeError: this two argument is not comparable!>>> list = [1,2,3,b,4,5]>>> list.index(3)2>>> list.index(b) # 成功找到!3>>> list.index(a) # 執行個體不同,但是self.x相等,屬於同一個。3>>> a in listTrue>>> b in listTrue