在Python中比较两个日期对象:TypeError:'<'不支持'datetime.date'实例和'method'。

12

这应该不太难,但我似乎无法让它起作用。我想在Python中比较两个datetime.date类型,但我一直收到Type Error:

from datetime import date  

class Vacancy(object):
    def __init__(self, date): #date is a datetime string of format 2017-13-03T00.00.000Z
        self.date = datetime.strptime(date[:-1], '%Y-%m-%dT%H:%M:%S.%f').date()

    def getDate(self):
         return self.date


all_objects = [o1, o2, o3, o4, ...] #contains objects of type Vacancy
for o in all_objects:
    earliestDate = date(2020, 1, 1) 
    if o.getDate() < earliestDate:
        earliestDate = o.getDate()

print(earliestDate)

TypeError: '<' not supported between instances of 'datetime.date' and 'method'

这对我来说毫无意义,因为:print(type(earliestDate))print(type(o.getDate())) 都会给出 <class 'datetime.date'>

我可能做错了什么?

编辑:添加了所有对象中的类示例代码

编辑2:正如你们中的许多人指出的那样,确实缺少了'()'。在我的实际代码中,我通过earliestDate = o.getDate进行了方法而非值的赋值。下次我会尽量遵守我的代码规范。感谢您们提供的见解,因为我确实来自Java,并且我还没有完全理解Python。


type(o.getDate) 还是 type(o.getDate()) - Willem Van Onsem
我的错误类型(o.getDate()) - k88
2
您能提供一个[mcve]来说明您的问题吗?o1,o2等是什么?您确定在您的实际代码中if o.getDate() < earliestDate:没有被读成if o.getDate < earliestDate:了吗? - SiHa
2
好的,上面的代码仍然不是MCVE:您没有展示如何实例化对象,并且日期时间字符串在很多方面都是错误的。但是,如果我添加这个:o1 = Vacancy('2017-03-13T00:00:00.000Z')并将列表更改为单个条目[o1],您的代码对我来说运行得非常好。 - SiHa
1
看起来你可能习惯了Java(getter)?你看过mypy吗?它可以帮助你追踪这种类型的问题。 - André Laszlo
显示剩余4条评论
3个回答

14

TypeError应该会提供你解决这个问题所需的所有信息。以下是如何解释它:

TypeError: '<' not supported between instances of 'datetime.date' and 'method'
  • '<' not supported 的意思是在使用 < 运算符时出现了错误,这一点你已经知道了。
  • 比较不起作用是因为你要比较的其中一件事不是 datetime.date 实例。这一点你也已经知道了。
  • 如果你使用 o.getDate 而不是 o.getDate(),你会得到 method 类型。在 Python 中,你可以像使用 lambda 表达式或函数一样传递方法值。然而,在这种情况下,这并不是你想要的,所以请确保在调用方法时使用 (),即使它不需要任何参数。
  • 错误消息中类型的顺序也很有趣。datetime.datemethod 之前,这意味着日期在左侧,有问题的值在右侧。在你的情况下,earliestDate 包含的是一个 method,而不是一个 datetime.date
  • 既然我们知道 earliestDate 是问题所在,那么它在哪里被更新?earliestDate = date(2020, 1, 1) 显然是一个日期,但是 earliestDate = o.getDate() 呢?它使用了括号,因此 o.getDate() 必须返回一个 method
  • 根据你的代码,Vacancyself.date 将始终设置为日期,否则将引发异常(类似于 ValueError: time data 'xxx' does not match format '%Y-%m-%dT%H:%M:%S.%f')。我猜你的代码看起来不一样,Vacancy 的初始化可能有些问题。这就是提供MCVE的好处 :)

1
你简洁明了的问题解决方式帮了我很多,谢谢! - k88

2
你重写了日期的定义,试试这样做(使用别名 dt 保持 datetime 命名空间)。一个好的实践是不要为你导入的库中的函数和对象命名本地变量或成员变量,例如你从 datetime 导入了 date,然后在 init 中使用 date 作为参数。
import datetime as dt   

class Vacancy(object):
    def __init__(self, date):
        self.date = date

    def getDate(self):
         return self.date


all_objects = [o1, o2, o3, o4, ...] #contains objects of type Vacancy
for o in all_objects:
    earliestDate = dt.date(2020, 1, 1) 
    if o.getDate() < earliestDate:
        earliestDate = o.getDate()

print(earliestDate)

额外的一点观察是,在Python中不需要定义getter和setter,因为变量是公开的。最好只需:

import datetime as dt   

class Vacancy(object):
    def __init__(self, date):
        self.date = date

all_objects = [o1, o2, o3, o4, ...] #contains objects of type Vacancy
for o in all_objects:
    earliestDate = dt.date(2020, 1, 1) 
    if o.date < earliestDate:
        earliestDate = o.date

如果您想确保日期成员变量不被修改,可以尝试以下代码:

class Vacancy(object):
    def __init__(self, date):
        self.date = date

    def getMinDate(self, other_date):
        if self.date < other_date:
            return dt.date(self.date)
        else:
            return other_date

all_objects = [o1, o2, o3, o4, ...] #contains objects of type Vacancy
earliestDate = dt.date(2020, 1, 1) 
for o in all_objects:
    earliestDate = o.getMinDate(earliestDate)

感谢指出Python不需要使用getter/setter。由于上面的代码并不是我的实际代码,所以日期导入并不是问题。对我来说,实际的类代码在另一个文件中。 - k88

0

当尝试将条件应用于列中的NULL值时,也会引发此错误。

解决方法:

  • 添加一个条件,仅在值不为null时执行该条件。
  • 删除null值
from datetime import date  

class Vacancy(object):
    def __init__(self, date): #date is a datetime string of format 2017-13-03T00.00.000Z
        self.date = datetime.strptime(date[:-1], '%Y-%m-%dT%H:%M:%S.%f').date()

    def getDate(self):
         return self.date


all_objects = [o1, o2, o3, o4, ...] #contains objects of type Vacancy
for o in all_objects:
    earliestDate = date(2020, 1, 1) 
    
    # NOT Null condition 
    if (o != None) and (earliestDate != None):
        if o.getDate() < earliestDate:
            earliestDate = o.getDate()

print(earliestDate)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接