Python 为什么可以';子类datetime.date?
为什么下面的代码(Python2.5.2)不起作用Python 为什么可以';子类datetime.date?,python,oop,datetime,subclass,Python,Oop,Datetime,Subclass,为什么下面的代码(Python2.5.2)不起作用 谢谢 以下是答案和可能的解决方案(使用函数或strtime而不是子类化) 您可能应该使用工厂函数,而不是创建子类: def first_day_of_the_year(year): return datetime.date(year, 1, 1) 你的功能没有被绕过;Python从来没有达到它会调用它的程度。由于datetime是在C中实现的,所以它在datetime中进行初始化。这是因为datetime是不可变的。您大概可以通过覆盖\u
谢谢 以下是答案和可能的解决方案(使用函数或strtime而不是子类化)
您可能应该使用工厂函数,而不是创建子类:
def first_day_of_the_year(year):
return datetime.date(year, 1, 1)
你的功能没有被绕过;Python从来没有达到它会调用它的程度。由于datetime是在C中实现的,所以它在
datetime中进行初始化。这是因为datetime是不可变的。您大概可以通过覆盖\uuuuu new\uuuuu
而不是\uuuuu init\uuuuu
来解决这个问题。但正如其他人所建议的,最好的方法可能根本不是对datetime进行子类化。您可以包装它,并向包装器添加扩展功能
以下是一个例子:
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
s属性。关于其他几个答案,这与在C中实现的日期本身没有任何关系。\uuuuu init\uuuuu
方法什么都不做,因为它们是不可变的对象,因此构造函数(\uuuuuu new\uuuuu
)应该完成所有工作。你会看到同样的行为子类化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参考资料,特别是关于\uuuuu new\uuuu
该页摘录(我的斜体):
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
主要用于允许不可变类型的子类(如int、str或tuple)自定义实例创建。为了自定义类的创建,它通常在自定义元类中被重写
datetime.datetime
也是一个不可变的类型
如果你认为:
- 在C中实现的对象不能子类化,或者
\uuuuu init\uuuuu
不会为C实现的对象调用,只调用\uuuu new\uuuuu
那么请尝试一下:
>>> 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
>>>
导入数组
>>>排列
>>>A类(数组.数组):
定义初始化(self,*args):
super(array.array,self)。\uuuuu init\uuuuu(*args)
打印“对于C中实现的对象,init很好”
>>>a=a('c')
对于用C实现的对象,init很好
>>>
另请参见谢谢,问题的链接就在钱上,但没有解释为什么它不起作用。问题的根源是什么?它能被克服吗?是的,这很酷,但我很好奇为什么子类不起作用(它是一个扩展类的差别),这是否可以克服……本杰明:请检查我的答案,并考虑纠正你的,因为它是迄今为止投票最多的;基本上,只有你的最后一句话可以被认为是有用的;其他人的消息是错误的。另外,请修复您的“它的”→“它的”和“(不是”→“(注”.@tΖΖΖΖΖΖΖΖΖΖΖΖΥ:你是对的。它实际上是子类化的。我会回到文档中,找出我犯了这个错误的地方。同时我正在修正答案。谢谢。投票表决通过文档链接,因为这似乎是唯一的答案。但是你的示例被破坏了。它只起作用,因为初始值设定项是可选参数。试试a=A('c',[],5,8)
!>>A=array.array('c',[],5,8)回溯(最近一次调用):文件“”,第1行,在TypeError:array()中最多取2个参数(4个给定)>>A=A('c',[],5,8)回溯(最近一次调用):文件“”,在TypeError:array()中的第1行最多取2个参数(4个给定)
什么是未损坏的示例?@mkiever
>>> import datetime
>>> class D(datetime.date):
def __new__(cls, year):
return datetime.date.__new__(cls, year, 1, 1)
>>> D(2008)
D(2008, 1, 1)
>>> 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
>>>