为什么以下功能不起作用(Python 2.5.2)?
>>> import datetime
>>> class D(datetime.date):
def __init__(self, year):
datetime.date.__init__(self, year, 1, 1)
>>> D(2008)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: function takes exactly 3 arguments (1 given)
我想创建一个类似于datetime.date
的类,但具有不同的__init__
函数。显然我的函数永远不会被调用。相反,原始的datetime.date.__init__
被调用并失败,因为它需要3个参数,而我要传递一个。
这里发生了什么?这是一个线索吗?
>>> datetime.date.__init__
<slot wrapper '__init__' of 'object' objects>
谢谢!
__init__
方法不执行任何操作,因为它们是immutable对象,因此构造函数(__new__
)应该完成所有工作。您会看到相同的行为将int,str等子类化。
>>> import datetime
>>> class D(datetime.date):
def __new__(cls, year):
return datetime.date.__new__(cls, year, 1, 1)
>>> D(2008)
D(2008, 1, 1)
__new__
special method的内容。该页节录(斜体):
__new__()
主要目的是允许immutable类型的子类(例如int,str或tuple)成为customize instance creation。为了自定义类的创建,它通常也被自定义元类覆盖。
datetime.datetime
也是不可变的类型。PS,如果您认为:
__init__
不会被C实现的对象调用,只有__new__
>>> import array
>>> array
<module 'array' (built-in)>
>>> class A(array.array):
def __init__(self, *args):
super(array.array, self).__init__(*args)
print "init is fine for objects implemented in C"
>>> a=A('c')
init is fine for objects implemented in C
>>>
http://www.mail-archive.com/[email protected]/msg192783.html
datetime.__new__
中而不是在datetime.__init__
中进行初始化。这是因为datetime是不可变的。您可以通过覆盖__new__
而不是__init__
来解决此问题。但是,正如其他人所建议的那样,最好的方法可能是根本不继承日期时间。def first_day_of_the_year(year):
return datetime.date(year, 1, 1)
包装,并将扩展功能添加到包装器。
这里是一个例子:class D2(object):
def __init__(self, *args, **kwargs):
self.date_object = datetime.date(*args, **kwargs)
def __getattr__(self, name):
return getattr(self.date_object, name)
这是它的工作方式:
>>> d = D2(2005, 10, 20) >>> d.weekday() 3 >>> dir(d) ['__class__', '__delattr__', '__dict__', '__doc__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'date_object'] >>> d.strftime('%d.%m.%Y') '20.10.2005' >>>
请注意,dir()
未列出datetime.date
的属性。