比较python中的日期,==有效,但< =产生错误

时间:2018-01-03 04:48:43

标签: python python-3.x datetime

我试图比较两个日期。此代码有效:

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)

它产生:

True
False

这些代码不起作用,我不知道原因:

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)

它产生了这个错误:

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

请注意,我更改的所有内容为==>=,为什么相等比较会产生TrueFalse,而大于比较会导致错误?

我将不胜感激任何帮助!

3 个答案:

答案 0 :(得分:10)

TL; DR

这是因为比较方法的定义方式。

为什么`==`是可比的,而`> =`在`time`对象之间并且输入`int`:

以下是time对象source code的副本:

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__返回False,而不是time个实例,而__ge__则调用_cmperror,其定义如下:

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

非常重要的编辑

虽然这个答案已经获得了一些积极的分数,但我错过了阅读你的问题,你使用了date个对象,而不是time个对象。

为什么`==`是可比较的,而`> =`在`date`对象之间并且输入`int`:

首先,与date个对象不同,time个对象的实现与__eq____ge__相同。它们都实际返回NotImplemented,因此对date对象的方法没有什么特别之处:

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

然而,与int __eq__对其他方法的比较有所不同。当int的对象具有无法比较的类型且False的{​​{1}}为__eq__时,NotImplemented会返回__ge__

NotImplemented返回的date将导致int方法的回退。由于int始终具有可比性,date == 0不会导致错误。

以下是一个例子:

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.

如果您不知道return NotImplemented是什么,请参阅doc的简短说明和引用:

  

当二进制[(__eq____ge__ ...)](或就地)方法返回NotImplemented时   解释器将尝试反射操作在另一种类型(或   其他一些后备,取决于运营商)。如果所有的尝试   返回NotImplemented,口译员会提出适当的答案   例外。错误地返回NotImplemented将导致a   误导性错误消息或返回的NotImplemented值   Python代码。

当从二进制方法返回NotImplemented时,它指的是二进制方法无法将自己与目标进行比较'类型。二进制方法的结果将取决于其他对象'二元方法。如果两个对象都返回NotImplemented,则会引发错误。

答案 1 :(得分:1)

正如其他人已经指出的那样,你不能使用date1 >= 0,因为两者的类型不同。

date1 == 0有效,因为您正在检查两个对象是否彼此相等。如果他们的类型不同,则答案自动为否,因此您将返回False

但是,在使用<><=>=时,您会检查某些内容是否大于或小于其他内容。如果你使用两个不同类型的对象,这些对象无法轻易地相互转换,那么就不会定义大于&#39;大于&#39;或者小于&#39;手段。因此,在您的情况下,date1的类型为datetime.date,而0的类型为int

答案 2 :(得分:0)

您正在尝试将date1与0进行比较。

这不起作用,因为date1datetime.date(请参阅最初如何定义)。所以基本上你要将dateint进行比较。

您只能比较相似的类型。