为什么我不能继承datetime.date?
为什么以下工作(Python 2.5.2)?为什么我不能继承datetime.date?
>>> 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)
这里的答案,以及可能的解决方案(使用功能或strptime,而不是子类)
http://www.mail-archive.com/[email protected]/msg192783.html
谢谢,问题的链接是正确的钱,但没有解释__why__它没有工作。问题的根源是什么?它能被克服吗? – Arkady 2008-12-29 23:20:14
你应该使用一个工厂函数,而不是创建一个子类:
def first_day_of_the_year(year):
return datetime.date(year, 1, 1)
是的,这很酷,但我很好奇,为什么子类不工作(它是如何扩展类使差异),以及这是否可以克服... – Arkady 2008-12-29 23:25:04
你的功能没有被绕过; Python只是从来没有达到它称之为的地步。由于日期时间在C中实现,因此它在datetime.__new__
而不是datetime.__init__
中进行初始化。这是因为日期时间是不可变的。你大概可以通过覆盖__new__
而不是__init__
来解决这个问题。但正如其他人所建议的那样,最好的方法可能根本不是继承datetime。
@Benjamin:请检查我的答案,并考虑纠正你的,因为这是迄今为止投票最多的;基本上,只有你的最后一句话才算有用。其他人误解了/ ing。此外,请修复您的“它”→“它”和“(不”→“(注意”) – tzot 2008-12-31 01:24:17
你可以包装它并添加扩展功能到你的包装。
下面是一个例子:
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
小号属性。
@ΤΖΩΤΖΙΟΥ:你说得对,它实际上是可分类的,我会回到文档并找出我制作的地方这个错误,同时我正在修复答案,谢谢 – muhuk 2008-12-31 07:26:10
请阅读Data model Python的参考,特别是关于__new__
special method。从该页面
摘录(我的斜体字):
__new__()
is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.
datetime.datetime
也是一个不变的类型。
PS如果你认为:
- 用C语言实现的对象不能被继承,或
-
__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://stackoverflow.com/questions/309 129 /为什么我不能继承dict和异常在python – hop 2008-12-29 23:16:29