Creating infinity and negative infinity in python for any object

I am working on a library that implements a data structure that works with any ordered data type - a range. Many operations (such as inversion) become interesting when you allow positive and negative infinity.

One goal is to make datetime objects work with this module and maintain infinity with non-numeric objects, I created INFINITY and 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() 

Unfortunately, this does not work for datetime objects when on the left side of the cmp () operation:

 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 

I was hoping I could get around this limitation using the cmp wrapper, which simply ensures that my objects are always called, but I really want to use the .sort() method, which will call the cmp call between these objects.

Is there a way to create an object that is really smaller than any other object and really larger than any other object?

Home module: https://github.com/axiak/py-rangeset

+4
source share
3 answers

from docs

To stop the comparison from returning to the default scheme, comparing the addresses of objects, comparing the date usually raises a TypeError if the other comparison is not also a date object. However, NotImplemented is returned instead if another comparison also has timetuple ().

to allow matching with datetime objects add a timetuple method, for example.

 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) 

output:

 1 -1 
+5
source

I'm not sure, but try overwriting __eq__ and __ne__ (or __cmp__ ) to see if they are called whenever you execute cmp. You should also know that cmp and __cmp__ are removed from python 3.

0
source

The problem is that cmp(now, INFINITY) equivalent to datetime.__cmp__(INFINITY) , which is defined directly in the datettime class. You can get around this by decapitating the date module, but it really is hacking.

I think what you really want is just a sort function that takes your class into account and always puts it in front or back depending on the infinity sign.

 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 ] 
0
source

Source: https://habr.com/ru/post/1385390/


All Articles