[英]Why can't I subclass datetime.date?
为什么以下不起作用(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>
谢谢!
关于其他几个答案,这与用 C 本身实现的日期没有任何关系。 __init__
方法什么都不做,因为它们是不可变的对象,因此构造函数( __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)
请阅读关于数据模型的 Python 参考,特别是关于__new__
特殊方法。
摘自该页面(我的斜体):
__new__()
主要用于允许不可变类型(如 int、str 或 tuple)的子类自定义实例创建。 它也通常在自定义元类中被覆盖,以自定义类创建。
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
>>>
这是答案和可能的解决方案(使用函数或 strptime 而不是子类化)
http://www.mail-archive.com/python-list@python.org/msg192783.html
你的功能没有被绕过; Python 永远不会到达调用它的地步。 由于 datetime 是在 C 中实现的,因此它在datetime.__new__
而不是datetime.__init__
。 这是因为日期时间是不可变的。 您大概可以通过覆盖__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
的属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.