Why doesn\'t the following work (Python 2.5.2)?
>>> import datetime
>>> class D(datetime.date):
def __init__(self, year):
You can wrap it and add extended functionality to your wrapper.
Here is an example:
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)
And here is how it works:
>>> 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'
>>>
Note that dir()
doesn't list datetime.date
s attributes.
Regarding several other answers, this doesn't have anything to do with dates being implemented in C per se. The __init__
method does nothing because they are immutable objects, therefore the constructor (__new__
) should do all the work. You would see the same behavior subclassing int, str, etc.
>>> import datetime
>>> class D(datetime.date):
def __new__(cls, year):
return datetime.date.__new__(cls, year, 1, 1)
>>> D(2008)
D(2008, 1, 1)
Please read the Python reference on Data model, especially about the __new__
special method.
Excerpt from that page (my italics):
__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
is also an immutable type.
PS If you think that:
__init__
doesn't get called for C implemented objects, only __new__
then please try it:
>>> 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
>>>
You should probably use a factory function instead of creating a subclass:
def first_day_of_the_year(year):
return datetime.date(year, 1, 1)
Here's the answer, and a possible solution (use a function or strptime instead of subclassing)
http://www.mail-archive.com/python-list@python.org/msg192783.html
You're function isn't being bypassed; Python just never gets to the point where it would call it. Since datetime is implemented in C, it does its initialization in datetime.__new__
not datetime.__init__
. This is because datetime is immutable. You could presumably get around this by overriding __new__
instead of __init__
. But as other people have suggested, the best way is probably not subclassing datetime at all.