Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么可以';子类datetime.date?_Python_Oop_Datetime_Subclass - Fatal编程技术网

Python 为什么可以';子类datetime.date?

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

为什么下面的代码(Python2.5.2)不起作用


谢谢

以下是答案和可能的解决方案(使用函数或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
>>>