在python中为任何对象创建无穷大和负无穷大

Mik*_*iak 4 python comparison magic-methods

我正在开发一个库,它实现了一个适用于任何有序数据类型的数据结构 - 一个范围集.当你允许正负无限时,许多操作(如反转)会变得有趣.

一个目标是让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()
Run Code Online (Sandbox Code Playgroud)

不幸的是,当在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
Run Code Online (Sandbox Code Playgroud)

我希望通过使用cmp包装器来解决这个限制,这只能确保我的对象总是被调用,但我真的想要使用这个.sort()方法,这将导致在这些对象之间调用cmp.

有没有办法创建一个真正小于任何其他对象的对象,并且真正比任何其他对象更大?

模块主页:https://github.com/axiak/py-rangeset

Anu*_*yal 5

来自文档

为了阻止比较回退到比较对象地址的默认方案,如果另一个比较不是日期对象,则日期比较通常会引发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)
Run Code Online (Sandbox Code Playgroud)

输出:

1    
-1
Run Code Online (Sandbox Code Playgroud)