簡體   English   中英

Python比較運算符重載

[英]Python comparison operator overloading

對於我的Python 2.7.3項目,我有一個名為custom_date的類,它有一個名為fixed_date的屬性:

from datetime import date
class custom_date():
    def __init__(self, fixed_date):
        self.fixed_date = fixed_date

    def __lt__(self, other):
        return self.fixed_date < other

    #__gt__, __ge__, __le__, __eq__, __ne__ all implemented the same way

我的想法是能夠直接將custom_date.fixed_date與內置date進行比較。

問題

如果我將custom_date對象與date對象進行比較,那很好。 但是,如果我將date對象與custom_date進行比較,則會返回TypeError

>>> from datetime import date
>>> x = custom_date(date(2013,2,1))
>>> y = date(2013,2,2)
>>> x > y
False
>>> y > x
TypeError: can't compare datetime.date to instance 

有沒有辦法解決?

我想我知道你為什么遇到問題。 檢查docs.python.org上的數據模型文檔

>>> y > x

要求:

y.__gt__(x)

x只是一個實例對象,而不是存儲在其中的fixed_date屬性:

>>> x
<__main__.custom_date instance at 0x020D78C8>
>>> x.fixed_date
datetime.date(2012, 2, 1)

讓它按照你設置的方式工作的一種方法是:

>>> y > x.fixed_date

我認為要“修復”這個,你可以使你的所有日期都是custom_date類型。 別人可能會為你提供更好的解決方案,我會留意,因為我也很好奇。

只需子類化date即可獲得此功能。 由於datetime對象是不可變的,因此需要使用__new__構造函數vs __init__

from datetime import date
class custom_date(date):
    def __new__(cls, year,month,day):
        return date.__new__(cls, year, month,day)

x = custom_date(2013,2,1)
y = date(2013,2,2)

print x<y
print y<x

打印:

True
False

由於比較的確定性類是LH類 ,因此左側的類需要具有正確的比較運算符來處理與右側類的比較。 如果任何一個類都沒有比較運算符,則實例按標識排序 - 它們的內存地址。 您的錯誤主要來自於嘗試將蘋果與橙色:身份與日期類進行比較。

請注意,曾經有一個在Python 2.1 中刪除rcmp來處理這些問題。 引入新的樣式類豐富的比較也導致__cmp__被棄用。

找到一個潛在的解決方案,以防其他人面臨同樣的問題。

Python datetime文檔

換句話說,date1 <date2當且僅當date1.toordinal()<date2.toordinal()。 為了阻止比較回退到比較對象地址的默認方案,如果另一個比較不是日期對象,則日期比較通常會引發TypeError。 但是,如果另一個comparand具有timetuple()屬性,則返回NotImplemented。 這個鈎子為其他類型的日期對象提供了實現混合類型比較的機會。 如果不是,當將日期對象與不同類型的對象進行比較時,除非比較為==或!=,否則會引發TypeError。 后一種情況分別返回False或True。

如果x.__op__(y)返回NotImplemented而不是引發TypeError ,Python將自動嘗試反向比較y.__rop__(x) (有關比較的更多信息,請參見此處 )。

但是,如果另一個對象不是date對象,則date會引發TypeError除非另一個對象實現了timetuple()屬性

所以解決方法是在我的類中添加一個虛擬的timetuple()方法。

from datetime import date
class custom_date():
    def __init__(self, fixed_date):
        self.fixed_date = fixed_date

    def __lt__(self, other):
        return self.fixed_date < other

    #__gt__, __ge__, __le__, __eq__, __ne__ all implemented the same way

    def timetuple():
        pass

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM