覆盖运算符 +约会 + Python 中的时间 = 日期时间

发布于 2024-10-01 09:30:16 字数 110 浏览 4 评论 0原文

我有几个扩展内置日期时间的类。*

有什么好的理由不重载 + (MyTime.__radd___) 以便 MyDate + MyTime 返回 MyDateTime?

I have a couple classes extending builtin datetime.*

Is there any good reason to not overload + (MyTime.__radd___) so MyDate + MyTime returns a MyDateTime?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

送舟行 2024-10-08 09:30: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

This is already implemented as a class method, 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

prints

2010-12-05 10:22:15
你另情深 2024-10-08 09:30:16

这通常会让人皱眉,因为你实际上是在组合而不是相加;这就是为什么实际的日期时间库有一个 combine 方法而不是以这种方式使用加法。

我不知道 Python 中有任何其他情况 的实例+ 生成 。因此,最小惊讶原则建议您只需提供一个combine 方法而不是重载加法。

This would generally be frowned upon because you're really combining rather than adding; this is why the actual datetime library has a combine method rather than using addition in this way.

I'm not aware of any other cases in Python where <instance of TypeA> + <instance of TypeB> produces <instance of TypeC>. Thus, the Principle of least astonishment suggests that you should simply provide a combine method rather than overload addition.

尬尬 2024-10-08 09:30:16

是的,至少有一个充分的理由不这样做:生成的实例与两个输入实例完全不同。这重要吗?我不这么认为——考虑一下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

所以,如果是我,我正在设计一个日期、时间、日期时间、TimeDelta 框架,我会允许:

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

并且对于这些:

date +/- timedelta
time +/- timedelta

如果 timedelta 没有,我将默认返回相同的类型如果 timedelta 确实具有其他类型,则引发异常,但会有一个设置可以控制它。另一种可能的行为是删除不需要的部分 - 因此日期与包含小时的时间增量相结合将删除小时并返回日期。

Yes, there is at least one good reason not to: the resulting instance is completely different from the two input instances. Is this important? I don't think so -- consider that date - date yields timedelta.

The way I see it:

  • Does adding two dates together make sense? No.
  • Does adding two times together make sense? No.
  • Does adding a date and a time together make sense? Yup!
  • Does adding a date and a timedelta togethor make sense? Maybe.
  • Does adding a time and a timedelta together make sense? Maybe.

and for subtraction

  • Does subtracting two dates make sense? Yes.
  • Does subtracting two times make sense? Yes.
  • Does subtracting a time from a date make sense? Nope.
  • Does subtracting a timedelta from a date make sense? Maybe.
  • Does subtracting a timedelta from a time make sense? Maybe.

Developing along the lines of what makes sense:

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

So, if it were me and I were designing a Date, Time, DateTime, TimeDelta framework, I would allow:

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

and for these:

date +/- timedelta
time +/- timedelta

I would default to returning the same type if the timedelta had none of the other type, and raising an exception if the timedelta did have some of the other type, but there would be a setting that would control that. The other possible behavior would be to drop the unneeded portion -- so a date combined with a timedelta that had hours would drop the hours and return a date.

绝情姑娘 2024-10-08 09:30:16

由于日期、时间和日期时间跨类型加减运算符的存在,我认为这很好,只要定义良好即可。

目前(2.7.2):

date = date + timedelta
date = date - timedelta
timedelta = date - date

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

我相信以下内容对于扩展来说也是合理的:

timedelta = time - time
datetime = date + time

我也打算建议以下内容,但是 time 对于 hour< 有非常具体的最小值和最大值/code>、分钟微秒,因此需要值的静默环绕或返回不同类型:

time = time + timedelta
time = time - timedelta

类似地,date 无法处理添加到其中的小于一天的 timedelta。我经常被告知只需在 Python 中使用 Duck Typing,因为这就是目的。 如果这是真的,那么我会提出以下完整的接口:

[date|datetime] = date + timedelta
[date|datetime] = date - timedelta
timedelta = date - date

[time|timedelta] = time + timedelta
[time|timedelta] = time - timedelta
timedelta = time - time

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

timedelta = timedelta + timedelta
timedelta = timedelta - timedelta

其中,考虑到 date 存在精度损失的情况(对于 timedelta' s 与部分天),它被提升为日期时间。同样,考虑到 time 存在精度损失的情况(对于产生超过一天的结果或负时间的 timedelta),它会提升为 >时间增量但是,我对[time|timedelta]不太满意。考虑到接口的其余部分从并行性和精度视图来看,这是有道理的,但我确实认为将时间环绕到正确的时间可能更优雅,从而更改所有[time|timedelta]简单地说就是时间,但不幸的是,这让我们失去了精度。

Due to the existence of the date, time, and datetime cross-type addition and subtraction operators, I would think that this is fine, so long as it is well defined.

Currently (2.7.2):

date = date + timedelta
date = date - timedelta
timedelta = date - date

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

I believe the following is also reasonable for an extension:

timedelta = time - time
datetime = date + time

I was going to suggest the following as well, but time has very specific min and max values for hour, minute, second, and microsecond, thus requiring a silent wraparound of values or returning of a different type:

time = time + timedelta
time = time - timedelta

Similarly, date cannot handle a timedelta of less than a day being added to it. Often I have been told to simply use Duck Typing with Python, because that's the intent. If that is true, then I would propose the following completed interface:

[date|datetime] = date + timedelta
[date|datetime] = date - timedelta
timedelta = date - date

[time|timedelta] = time + timedelta
[time|timedelta] = time - timedelta
timedelta = time - time

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

timedelta = timedelta + timedelta
timedelta = timedelta - timedelta

In which, given the case that date has precision loss (for timedelta's with partial days), it is promoted to datetime. Similarly, given the case that time has precision loss (for timedelta's that yield a result of more than one day, or negative time), it is promoted to timedelta. However, I'm not fully comfortable with [time|timedelta]. It makes sense given the rest of the interface from parallelism and precision views, but I do think it might be more elegant to just wraparound the time to the proper hour, thus changing all the [time|timedelta]'s to simply time, but unfortunately that leaves us with lost precision.

怎言笑 2024-10-08 09:30:16

在我看来,运算符重载最有价值的用途是可以组合许多输入值的情况。您永远不想处理:

concat(concat(concat("Hello", ", "), concat("World", "!")), '\n');

distance = sqrt(add(add(x*x, y*y), z*z));

因此我们重载数学符号以创建更直观的语法。处理这个问题的另一种方法是可变参数函数,比如Scheme中的+

对于 date + time = datetime,添加 datetime + datetimedatetime + timedatetime 没有任何意义+ date,这样你就永远不会遇到上面那样的情况。

在我看来,再次强调,正确的做法是使用构造函数方法。在 C++ 等强类型语言中,您将拥有 DateTime(const Date &d, const Time &t)。使用Python的动态类型,我猜他们给函数起了一个名字,datetime.combine(date, time),以便当输入变量的类型在代码中不可见时使代码更清晰。

In my opinion, the most valuable uses of operator overloading are situations where many input values can be combined. You'd never want to deal with:

concat(concat(concat("Hello", ", "), concat("World", "!")), '\n');

or

distance = sqrt(add(add(x*x, y*y), z*z));

So we overload math symbols to create a more intuitive syntax. Another way to deal with this problem is variadic functions, like + in Scheme.

With your date + time = datetime, it doesn't make sense to add datetime + datetime, datetime + time, or datetime + date, so you could never encounter a situation like those above.

In my opinion, once again, the right thing is to use a constructor method. In a language with strong typing like C++, you'd have DateTime(const Date &d, const Time &t). With Python's dynamic typing, I guess they gave the function a name, datetime.combine(date, time), to make the code clearer when the types of the input variables are not visible in the code.

泅渡 2024-10-08 09:30:16

我认为最重要的是功能和效率。当然,使用简单的 + 运算符会更容易使用,但我不确定功能。

如果我们将它与 datetime.combine 进行比较,combine 的作用是:

dt = date(2011,01,01)
tm = time(20,00)
dtm = datetime.combine(dt, tm)

对于 dtm

  • 如果 dt 是日期对象tm 是一个时间对象,date 信息取自 dttime 信息和 < 则从 tm 对象获取 em>tzinfo
  • 如果 dtdatetime 对象, ,而不是其时间tzinfo 属性将被忽略。

从这个角度来看,使用 datetime 对象似乎不是简单的对象,而是具有不同属性的更复杂的结构,例如时区信息

也许这就是为什么 datetime 对象有一些附加函数,用于格式化对象类型和对象的数据结构。

Python 有一句座右铭(类似的东西):

在Python中,没有什么是一成不变的,如果你知道自己在做什么。如果没有,最好保留库函数原样...

因此,在我看来,最好使用重载 + 运算符的 combine

I guess most important things are functionality and efficiency. Of course using a simple + operator will be easier to use, but i am not sure about functionality.

If we compare it to datetime.combine, What combine do is:

dt = date(2011,01,01)
tm = time(20,00)
dtm = datetime.combine(dt, tm)

For dtm

  • If dt is a date object and tm is a time object, than date info is taken from dt, time info and tzinfo is taken from tm object
  • if dt is a datetime object, than its time and tzinfo attributes will be ignored.

From that point of view, working with datetime objects do not seem to be simple objects, but more compex structures with diffrent attributes, like timezone info.

Probably thats why datetime objects have some additional functions that is used for formatting object type and data structure of the object.

Python have a motto (something like that):

In python, nothing is unchangable, if you know what you are doing. If not, it is better to leave library functions as they are...

So, in my opinion, it is better you use combine that overloading + operator

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文