Overloading ctor doesn't work?

Kent Johnson kent3737 at yahoo.com
Thu Jan 20 15:23:01 EST 2005


Paul McGuire wrote:
> "Kent Johnson" <kent3737 at yahoo.com> wrote in message
> news:41effd30$1_1 at newspeer2.tds.net...
> 
>>>Martin Häcker wrote:
>>>
>>>
>>>>Hi there,
>>>>
>>>>I just tried to run this code and failed miserably - though I dunno
>>>>why. Could any of you please enlighten me why this doesn't work?
>>
>>Here is a simpler test case. I'm mystified too:
>>
>>from datetime import datetime
>>
>>class time (datetime):
>>   def __init__(self, hours=0, minutes=0, seconds=0, microseconds=0):
>>     datetime.__init__(self, 2001, 10, 31, hours, minutes, seconds,
> 
> microseconds)
> 
>>print time(1,2,3,4) # => 0001-02-03 04:00:00
>>print time()        # => TypeError: function takes at least 3 arguments (0
> 
> given)
> 
>>
>>What happens to the default arguments to time.__init__? What happens to
> 
> the 2001, 10, 31 arguments
> 
>>to datetime.__init__?
>>
>>I would expect the output to be
>>2001-10-31 01:02:03.000004
>>2001-10-31 00:00:00.000000
>>
>>Kent
> 
> 
> I can't explain this behavior, but this version does work (uses
> datetime.combine instead of ctor)
> 
> -- Paul
> 
> 
> from datetime import datetime, date as dt_date, time as dt_time
> 
> class time_d (datetime):
>     def __new__(cls, *args):
>         # default to no microseconds
>         if len(args)==3:
>             args = args + (0,)
>         if len(args)==4:
>             tmpdate = datetime.today()
>             h, mi, s, ms = args
>             return datetime.combine(tmpdate, dt_time(h,mi,s,ms))
>         elif len(args)==7:
>             y,m,d,h,mi,s,ms = args
>             return datetime.combine(dt_date(y,m,d), dt_time(h,mi,s,ms))
>         else:
>             raise TypeError, "wrong number of args"
> 
> print time_d(2001,10,31,1,2,3,4)
> print time_d(1,2,3,4)
> print time_d(1,2,3)


Ah, right. The light turns on...

datetime is immutable so overriding the constructor doesn't change the constructed object. You have 
to override __new__ instead.
http://www.python.org/2.2.1/descrintro.html#__new__

This works:

from datetime import datetime

class time (datetime):
     def __new__(cls, hours=0, minutes=0, seconds=0, microseconds=0):
         return datetime.__new__(cls, 2001, 10, 31, hours, minutes, seconds, microseconds)

print time(1,2,3,4) # => 2001-10-31 01:02:03.000004
print time()        # => 2001-10-31 00:00:00

Kent

> 
> 
> 



More information about the Python-list mailing list