在Python中重载运算符+使日期+时间=日期时间

7 投票
6 回答
2388 浏览
提问于 2025-04-16 06:45

我有几个类是从内置的日期时间类扩展出来的。

有没有什么好的理由不去重载加号(MyTime.__radd___),让我的日期(MyDate)和时间(MyTime)相加时返回一个日期时间(MyDateTime)呢?

6 个回答

4

是的,确实有一个很好的理由不这样做:结果的实例和两个输入的实例完全不同。这重要吗?我觉得不重要——想想看,date - date 的结果是 timedelta

我个人的看法是:

  • 把两个日期加在一起有意义吗?没有。
  • 把两个时间加在一起有意义吗?没有。
  • 把一个日期和一个时间加在一起有意义吗?有!
  • 把一个日期和一个时间差加在一起有意义吗?可能。
  • 把一个时间和一个时间差加在一起有意义吗?可能。

至于减法:

  • 把两个日期相减有意义吗?有。
  • 把两个时间相减有意义吗?有。
  • 把一个时间从一个日期中减去有意义吗?没有。
  • 把一个时间差从一个日期中减去有意义吗?可能。
  • 把一个时间差从一个时间中减去有意义吗?可能。

根据什么有意义来发展:

date + time      => datetime
date + timedelta => date | datetime or exception or silently drop time portion

time + date => datetime
time + timedelta => time | wrap-around or exception

date - date      => timedelta
date - timedelta => date | datetime or exception or silently drop time portion

time - time      => timedelta
time - timedelta => time | wrap-around or exception

datetime + timedelta => datetime
datetime - timedelta => datetime

所以,如果是我来设计一个日期、时间、日期时间和时间差的框架,我会允许:

date + time
date - date
time - time
datetime + timedelta
datetime - timedelta

对于这些:

date +/- timedelta
time +/- timedelta

如果时间差没有其他类型的内容,我会默认返回相同的类型;如果时间差有其他类型的内容,则会抛出异常,但会有一个设置来控制这个行为。另一种可能的行为是丢弃不需要的部分——比如一个日期和一个包含小时的时间差结合时,会丢掉小时,返回一个日期。

16

这个功能已经作为一个类的方法实现了,具体可以查看datetime.datetime.combine

import datetime
d = datetime.date(2010, 12, 5)
t = datetime.time(10, 22, 15)
dt = datetime.datetime.combine(d, t)
print dt

输出结果是

2010-12-05 10:22:15
12

一般来说,这种做法是不太被认可的,因为你实际上是在“组合”而不是“相加”。这就是为什么真正的日期时间库里有一个combine方法,而不是用加法来处理。

我不知道在Python中还有其他情况是<TypeA的实例> + <TypeB的实例>会产生<TypeC的实例>。因此,最小惊讶原则建议你应该提供一个combine方法,而不是重载加法。

撰写回答