簡體   English   中英

在python中為任何對象創建無窮大和負無窮大

[英]Creating infinity and negative infinity in python for any object

我正在開發一個庫,它實現了一個適用於任何有序數據類型的數據結構 - 一個范圍集。 當你允許正負無限時,許多操作(如反轉)會變得有趣。

一個目標是讓datetime對象與該模塊一起使用,並且在使用非數字對象支持infinity時,我創建了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()

不幸的是,當在cmp()操作的左側時,這對datetime對象不起作用:

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()方法,這將導致在這些對象之間調用cmp。

有沒有辦法創建一個真正小於任何其他對象的對象,並且真正比任何其他對象更大?

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

來自文檔

為了阻止比較回退到比較對象地址的默認方案,如果另一個比較不是日期對象,則日期比較通常會引發TypeError。 但是,如果另一個comparand具有timetuple()屬性,則返回NotImplemented。

所以為了與datetime對象進行比較,可以添加一個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

我不太確定但是嘗試覆蓋__eq____ne__ (或__cmp__ )以查看它們是否在您執行cmp時被調用。 您還應該知道從python 3中刪除了cmp和__cmp__

問題是cmp(now, INFINITY)等同於datetime.__cmp__(INFINITY) ,它直接在datettime類上定義。 你可以通過猴子修補dateetime模塊來解決這個問題,但那確實是個hackish。

我認為你真正想要的只是一個排序函數,它考慮到你的類,並始終根據無窮大的符號將它放在前面或后面。

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
]

暫無
暫無

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

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