覆盖运算符 +约会 + Python 中的时间 = 日期时间
我有几个扩展内置日期时间的类。*
有什么好的理由不重载 + (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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这已经作为类方法实现了,
datetime.datetime.combine
:
打印
This is already implemented as a class method,
datetime.datetime.combine
:prints
这通常会让人皱眉,因为你实际上是在组合而不是相加;这就是为什么实际的日期时间库有一个 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 acombine
method rather than overload addition.是的,至少有一个充分的理由不这样做:生成的实例与两个输入实例完全不同。这重要吗?我不这么认为——考虑一下
date - date
产生timedelta
。我的看法是:
对于减法
沿着有意义的方向进行开发:
所以,如果是我,我正在设计一个日期、时间、日期时间、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
yieldstimedelta
.The way I see it:
and for subtraction
Developing along the lines of what makes sense:
So, if it were me and I were designing a Date, Time, DateTime, TimeDelta framework, I would allow:
and for these:
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.
由于日期、时间和日期时间跨类型加减运算符的存在,我认为这很好,只要定义良好即可。
目前(2.7.2):
我相信以下内容对于扩展来说也是合理的:
我也打算建议以下内容,但是
time
对于hour< 有非常具体的最小值和最大值/code>、
分钟
、秒
和微秒
,因此需要值的静默环绕或返回不同类型:类似地,
date
无法处理添加到其中的小于一天的timedelta
。我经常被告知只需在 Python 中使用 Duck Typing,因为这就是目的。 如果这是真的,那么我会提出以下完整的接口:其中,考虑到
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):
I believe the following is also reasonable for an extension:
I was going to suggest the following as well, but
time
has very specific min and max values forhour
,minute
,second
, andmicrosecond
, thus requiring a silent wraparound of values or returning of a different type:Similarly,
date
cannot handle atimedelta
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:In which, given the case that
date
has precision loss (fortimedelta
's with partial days), it is promoted todatetime
. Similarly, given the case thattime
has precision loss (fortimedelta
's that yield a result of more than one day, or negative time), it is promoted totimedelta
. 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 simplytime
, but unfortunately that leaves us with lost precision.在我看来,运算符重载最有价值的用途是可以组合许多输入值的情况。您永远不想处理:
或
因此我们重载数学符号以创建更直观的语法。处理这个问题的另一种方法是可变参数函数,比如Scheme中的
+
。对于
date + time = datetime
,添加datetime + datetime
、datetime + time
或datetime 没有任何意义+ 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:
or
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 adddatetime + datetime
,datetime + time
, ordatetime + 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.我认为最重要的是功能和效率。当然,使用简单的
+
运算符会更容易使用,但我不确定功能。如果我们将它与
datetime.combine
进行比较,combine
的作用是:对于 dtm
dt
是日期对象tm
是一个时间对象,date 信息取自dt
、time 信息和 < 则从tm
对象获取 em>tzinfodt
是 datetime 对象, ,而不是其时间 和 tzinfo 属性将被忽略。从这个角度来看,使用
datetime
对象似乎不是简单的对象,而是具有不同属性的更复杂的结构,例如时区信息。也许这就是为什么
datetime
对象有一些附加函数,用于格式化对象类型和对象的数据结构。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
, Whatcombine
do is:For dtm
dt
is a date object andtm
is a time object, than date info is taken fromdt
, time info and tzinfo is taken fromtm
objectdt
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):
So, in my opinion, it is better you use
combine
that overloading+
operator