如果你使用__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)
yields
10:00:00
如果你覆盖__init__
, 但不是__new__
, then DT.timedelta.__new__
被叫到before your Hours.__init__
。注意
import datetime as DT
class Hours(DT.timedelta):
def __init__(self, hours):
print(self)
x = Hours(10)
prints 10 days, 0:00:00
。这表明DT.timedelta.__new__
在您有机会配置它之前,已经将 timedelta 设置为 10 天Hours.__init__
.
而且,DT.timedelta
是一个不可变的对象——你不能改变days
or seconds
or microseconds
对象被实例化后。 Python 使用以下方法创建不可变对象__new__
方法,并且通常不做任何事情__init__
方法。可变对象则相反:它们将对象配置为__init__
并且不要做任何事情__new__
.
Per the docs http://www.python.org/download/releases/2.2.3/descrintro/#__new__:
当对数字和字符串等不可变内置类型进行子类化时,
有时在其他情况下,静态方法__new__
来了
派上用场。__new__
是实例构建的第一步,调用
前__init__
. The __new__
方法以类作为其调用
第一个参数;它的责任是返回一个新的实例
班级。将此与__init__
: __init__
用实例调用
作为它的第一个参数,并且它不返回任何内容;它是
职责是初始化实例......
所有这一切都是为了让不可变类型可以保留它们的
不变性,同时允许子类化。
(如果不可变对象执行配置__init__
,那么你可以通过调用来改变不可变的immutable.__init__
。显然,我们不希望这样,所以immutable.__init__
一般什么都不做。)
另请注意,除非您计划将新方法添加到您的Hours
类,它会更简单,因此最好只使用一个函数:
def hours(hours):
return DT.timedelta(hours=hours)