Date comparison in python, == works, but <= creates an error

I am trying to compare two dates. This code works:

 import datetime todays_date = datetime.date.today() date1 = datetime.date(2006, 3, 15) date2 = datetime.date(2009, 4, 30) print(date1 != date2) print(date1 == 0) 

He produces:

 True False 

This code does not work, and I do not know why:

 import datetime todays_date = datetime.date.today() date1 = datetime.date(2006, 3, 15) date2 = datetime.date(2009, 4, 30) print(date1 != date2) print(date1 >= 0) 

It produces this error:

 File 'datetime.py', Line 363: AttributeError: 'int' object has no attribute '__name__' 

Note that everything I changed was from == to >= , why does equality comparison result in True or False , and more than comparaison leads to an error?

I would be grateful for any help!

+5
source share
3 answers

TL DR

This is because of how comparison methods are defined.


The reason why `==` is comparable, and `> =` is not between the objects `time` and type` int`:

Here's a copy of the source code for the time object:

 def __eq__(self, other): if isinstance(other, time): return self._cmp(other, allow_mixed=True) == 0 else: return False def __ge__(self, other): if isinstance(other, time): return self._cmp(other) >= 0 else: _cmperror(self, other) 

__eq__ returns False when it is not an instance of time , while __ge__ raises a _cmperror , which is defined as follows:

 def _cmperror(x, y): raise TypeError("can't compare '%s' to '%s'" % ( type(x).__name__, type(y).__name__)) 

It is very important to edit

Although this answer has already received some positive ratings, but I missed your question, you used date objects, not time .

The reason why `==` is comparable, and `> =` is not between date objects and type `int`:

First of all, date objects, unlike time objects, are implemented the same way for __eq__ and __ge__ . Both of them actually return NotImplemented , so there is nothing special about the date object methods:

 def __eq__(self, other): if isinstance(other, date): return self._cmp(other) == 0 return NotImplemented def __ge__(self, other): if isinstance(other, date): return self._cmp(other) >= 0 return NotImplemented 

Unlike others, comparing int __eq__ with other methods. int returns False when the object is of a disparate type for __eq__ and NotImplemented for __ge__ .

NotImplemented returned by date will roll back in int methods. Since int always equally comparable, date == 0 does not result in an error.

Here is an example:

 class LikeDate: def __eq__(self, other): if isinstance(other, LikeDate): return True else: return NotImplemented def __ge__(self, other): if isinstance(other, LikeDate): return True else: return NotImplemented class LikeInt: def __eq__(self, other): if isinstance(other, LikeInt): return True else: return False def __ge__(self, other): if isinstance(other, LikeInt): return True else: return NotImplemented a = LikeDate() b = LikeInt() print(a == b) # False print(a == 0) # False, because int provides an __eq__ method that returns False print(a >= 0) # Error, because nether LikeDate nor int provides a definite comparison for __ge__ print(a >= b) # Error, because neither objects provide a comparable __ge__ 

You can run this example here.


If you don't know what return NotImplemented , here is a short explanation and quote from doc :

When the binary [( __eq__ , __ge__ ...)] method (or in place) returns a NotImplemented interpreter will try to reflect the operation on another type (or some other reserve, depending on the operator). If all attempts return NotImplemented , the interpreter will raise a corresponding exception. An incorrect NotImplemented return will result in a misleading error message or return value for the NotImplemented Python code.

When NotImplemented returns from a binary method, it refers to the fact that the binary method cannot be compared to the type of targets. The result of the binary method will depend on the binary method of other objects. If both objects return NotImplemented , an error occurs.

+10
source

As others have already pointed out, you cannot use date1 >= 0 , because both do not have the same type.

date1 == 0 works because you are checking to see if two objects match each other. If their types are different, the answer is no automatically and you get False back.

However, when using < , > , <= , >= you check if something bigger or smaller is something bigger or something else. If you use two objects with different types that cannot be trivially converted to each other, then it is not defined what means more than or less. So, in your case, date1 is of type datetime.date , and 0 is of type int .

+1
source

You are trying to compare date1 with 0.

This will not work, as date1 is datetime.date (see how you define it initially). So you are comparing date with int .

You can only compare similar types.

0
source

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


All Articles