[英]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__
被棄用。
找到一個潛在的解決方案,以防其他人面臨同樣的問題。
換句話說,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.