jan*_*jan 8 python datetime timedelta python-2.7
为方便起见,我想创建datetime.timedelta的子类.我们的想法是定义一个类:
class Hours(datetime.timedelta):
def __init__(self, hours):
super(Hours, self).__init__(hours=hours)
Run Code Online (Sandbox Code Playgroud)
所以我可以快速创建这样的timedeltas:
x = Hours(n)
Run Code Online (Sandbox Code Playgroud)
但是,上面的代码生成n天而不是n小时的timedelta.作为示例,请查看以下ipython会话:
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
Run Code Online (Sandbox Code Playgroud)
我无法解释这一点.有人吗?
unu*_*tbu 12
如果您使用__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)
Run Code Online (Sandbox Code Playgroud)
产量
10:00:00
Run Code Online (Sandbox Code Playgroud)
如果你覆盖__init__
,但不是__new__
,那么在你的之前DT.timedelta.__new__
调用.注意Hours.__init__
import datetime as DT
class Hours(DT.timedelta):
def __init__(self, hours):
print(self)
x = Hours(10)
Run Code Online (Sandbox Code Playgroud)
打印10 days, 0:00:00
.这表明DT.timedelta.__new__
在你有机会配置它之前已经将timedelta设置为10天Hours.__init__
.
此外,DT.timedelta
是不可变对象-你不能改变days
或seconds
或microseconds
对象实例化后.Python通过使用该__new__
方法创建不可变对象,并且通常不在该__init__
方法中执行任何操作.可变对象执行相反的操作:它们配置对象__init__
并且不执行任何操作__new__
.
根据文档:
当子类化不可变的内置类型(如数字和字符串)时,偶尔在其他情况下,静态方法
__new__
会派上用场.__new__
是实例构造的第一步,之前调用过__init__
.__new__
调用该方法时将类作为其第一个参数; 它的职责是返回该类的新实例.将此与__init__
以下__init__
内容进行比较:以实例作为其第一个参数进行调用,并且它不会返回任何内容; 它的职责是初始化实例....所有这些都是这样做的,这样不可变类型可以在允许子类化的同时保留它们的不变性.
(如果不可变对象执行配置__init__
,那么你可以通过调用来改变不可变的immutable.__init__
.显然,我们不希望这样,所以immutable.__init__
通常什么都不做.)
另请注意,除非您计划在类中添加新方法Hours
,否则它会更简单,因此更好地使用函数:
def hours(hours):
return DT.timedelta(hours=hours)
Run Code Online (Sandbox Code Playgroud)