gpt4 book ai didi

python - 子类化 datetime.timedelta 时的奇怪行为

转载 作者:太空狗 更新时间:2023-10-29 20:49:52 27 4
gpt4 key购买 nike

为了方便起见,我想创建 datetime.timedelta 的子类。这个想法是这样定义一个类:

class Hours(datetime.timedelta):
def __init__(self, hours):
super(Hours, self).__init__(hours=hours)

这样我就可以像那样快速创建时间增量:

x = Hours(n)

但是,上面的代码产生了 n 天而不是 n 小时的时间增量。例如,查看以下 ipython session :

In [1]: import datetime

In [2]: class Hours(datetime.timedelta):
...: def __init__(self, hours):
...: super(Hours, self).__init__(hours=hours)
...:

In [3]: print(Hours(10))
Out[3]: 10 days, 0:00:00

我无法解释这个。有人吗?

最佳答案

如果您使用 __new__,而不是 __init__:

import datetime as DT
class Hours(DT.timedelta):
def __new__(self, hours):
return DT.timedelta.__new__(self, hours=hours)
x = Hours(10)
print(x)

产量

10:00:00

如果您覆盖 __init__,但不覆盖 __new__,则 DT.timedelta.__new__ 会在您的Hours.__init__。注意事项

import datetime as DT
class Hours(DT.timedelta):
def __init__(self, hours):
print(self)

x = Hours(10)

打印 10 天,0:00:00。这表明 DT.timedelta.__new__ 已经将 timedelta 设置为 10 天,您甚至没有机会在 Hours.__init__ 中配置它。

此外,DT.timedelta 是一个不可变对象(immutable对象)——您无法更改dayssecondsmicroseconds 在对象被实例化之后。 Python通过__new__方法创建不可变对象(immutable对象),一般不会在__init__方法中做任何事情。可变对象恰恰相反:它们在 __init__ 中配置对象,在 __new__ 中不做任何事情。


根据 the docs :

When subclassing immutable built-in types like numbers and strings, and occasionally in other situations, the static method __new__ comes in handy. __new__ is the first step in instance construction, invoked before __init__. The __new__ method is called with the class as its first argument; its responsibility is to return a new instance of that class. Compare this to __init__: __init__ is called with an instance as its first argument, and it doesn't return anything; its responsibility is to initialize the instance....

All this is done so that immutable types can preserve their immutability while allowing subclassing.

(如果不可变对象(immutable对象)在 __init__ 中执行配置,那么您可以通过调用 immutable.__init__ 来改变不可变对象(immutable对象)。显然,我们不希望这样,所以 immutable.__init__ 通常什么都不做。)


另请注意,除非您计划向您的 Hours 类添加新方法,否则使用函数会更简单,因此更好:

def hours(hours):
return DT.timedelta(hours=hours)

关于python - 子类化 datetime.timedelta 时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22531489/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com