2011-12-08 81 views
4

我正在研究一個庫,該庫實現了可以與任何有序數據類型(範圍集)一起工作的數據結構。當你允許正面和負面的無限時,許多操作(如倒置)變得有趣。在python中爲任何對象創建無窮大和負無窮大

一個目標是讓datetime對象與該模塊工作,並與非數字對象支持無限大,我創建INFINITY和NEGATIVE_INFINITY:

class _Indeterminate(object): 
    def __eq__(self, other): 
     return other is self 

@functools.total_ordering 
class _Infinity(_Indeterminate): 
    def __lt__(self, other): 
     return False 
    def __gt__(self, other): 
     return True 
    def __str__(self): 
     return 'inf' 
    __repr__ = __str__ 

@functools.total_ordering 
class _NegativeInfinity(_Indeterminate): 
    def __lt__(self, other): 
     return True 
    def __gt__(self, other): 
     return False 
    def __str__(self): 
     return '-inf' 

INFINITY = _Infinity() 
NEGATIVE_INFINITY = _NegativeInfinity() 

不幸的是,這並不爲工作datetime對象時,在CMP()操作的左手邊:

In [1]: from rangeset import * 
In [2]: from datetime import datetime 
In [3]: now = datetime.now() 
In [4]: cmp(INFINITY, now) 
Out[4]: 1 
In [5]: cmp(now, INFINITY) 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
/home/axiak/Documents/rangeset/<ipython-input-5-c928d3687d92> in <module>() 
----> 1 cmp(now, INFINITY) 

TypeError: can't compare datetime.datetime to _Infinity 

我希望我可以通過使用CMP的包裝,只是確保我的對象總是叫繞過這個限制,但我真的想使用.sort() m這將導致在這些對象之間調用cmp。

有沒有什麼辦法可以創建一個比其他任何對象都小得多的對象,並且真的比其他任何對象都要大?

模塊主頁:https://github.com/axiak/py-rangeset

回答

5

docs

爲了去除,以落回 比較對象地址默認方案停止比較也應該意識到,日期比較正常提高TypeError 如果另一個比較不是一個日期對象。但是,如果另一個比較具有 timetuple()屬性,則返回NotImplemented而不返回。

因此爲了與日期時間對象進行比較,可以添加timetuple方法,例如,

class _Infinity(object): 

    def __lt__(self, other): 
     return False 

    def __gt__(self, other): 
     return True 

    def timetuple(self): 
     return tuple() 

import datetime 
INF = _Infinity() 
now = datetime.datetime.now() 
print cmp(INF, now) 
print cmp(now, INF) 

輸出:

1  
-1 
+0

這是正確的答案,謝謝! –

0

我真的不知道,但嘗試覆蓋__eq____ne__(或__cmp__)看看,只要你做的CMP他們被稱爲。你認爲CMP和__cmp__從蟒蛇3

0

問題是,cmp(now, INFINITY)相當於datetime.__cmp__(INFINITY)其直接限定在datettime類。你可以通過猴子修補日期時間模塊來解決這個問題,但那真的很危險。

我想你真正想要的只是一種功能,考慮到你的類,並始終將其置於視無限的符號前面或後面。

def order(x, y): 
    if isinstance(x,_Infinity): 
     return -1 
    if isinstance(y, _Infinity): 
     return 1 
    elif isinstance(x, _NegativeInfinity): 
     return 1 
    elif isinstance(y, _NegativeInfinity): 
     return -1 
    else: 
     return cmp(x,y) 

>>> sorted([datetime.datetime.now(), datetime.datetime.now(), INFINITY, NEGATIVE_INFINITY], cmp=order) 
[ 
    NEGATIVE_INFINITY, 
    datetime.datetime(2011, 12, 8, 13, 38, 47, 428626), 
    datetime.datetime(2011, 12, 8, 13, 38, 47, 428661), 
    INFINITY 
]