By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,089 Members | 2,432 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,089 IT Pros & Developers. It's quick & easy.

More puzzling behavior while subclassing datetime

P: n/a
With assistance from Gabriel and Frederik (and a few old threads in
c.l.p.) I've been making headway on my specialized datetime class. Now
I'm puzzled by behavior I didn't expect while attempting to use some of
the alternate datetime constructors. Specifically, it appears if I
call GeneralizedTime.now() it calls the __new__ method of my class but
treats keyword arguments as if they were positional.

My class:

class GeneralizedTime(datetime):
def __new__(cls, time=None, *args, **kwargs):
print time, args, kwargs
if isinstance(time, str):
timeValues, tzOffset = cls.stringToTimeTuple(time)
return datetime.__new__(cls, tzinfo=GenericTZ(tzOffset),
**timeValues)
elif isinstance(time, datetime):
timeValues = time.timetuple()[:6]
tzOffset = time.utcoffset()
return datetime.__new__(cls, tzinfo=GenericTZ(tzOffset),
*timeValues)
elif time is None:
print "Still gotta figure out now to do this one..."
else:
raise Invalidtime(time)
@staticmethod
def stringToTimeTuple(timeString):
... regex that parses timeString ...
>>GeneralizedTime.today()
2006 (11, 16, 0, 35, 18, 747275, None) {}
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "gentime.py", line 106, in __new__
raise InvalidTime(time)
gentime.InvalidTime: 2006

So it appears the time tuple is being passed to
GeneralizedTime.__new__, but the first value is being assigned to the
"time" argument.

Is this a side effect of how datetime is implemented? Or am I doing
something screwy?

Thanks!

-Ben

Nov 16 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a

in****@gmail.com wrote:
With assistance from Gabriel and Frederik (and a few old threads in
c.l.p.) I've been making headway on my specialized datetime class. Now
I'm puzzled by behavior I didn't expect while attempting to use some of
the alternate datetime constructors. Specifically, it appears if I
call GeneralizedTime.now() it calls the __new__ method of my class but
treats keyword arguments as if they were positional.

My class:

class GeneralizedTime(datetime):
def __new__(cls, time=None, *args, **kwargs):
datetime.datetime() takes these arguments: year, month, day[, hour[,
minute[, second[, microsecond[, tzinfo]]]]]), see
http://docs.python.org/lib/datetime-datetime.html
print time, args, kwargs
if isinstance(time, str):
timeValues, tzOffset = cls.stringToTimeTuple(time)
return datetime.__new__(cls, tzinfo=GenericTZ(tzOffset),
**timeValues)
elif isinstance(time, datetime):
timeValues = time.timetuple()[:6]
time.timetuple() does not exist, see
http://docs.python.org/lib/module-time.html, time is represented as a
tuple. checkout time.mktime() on how to convert to a tuple to a time
tzOffset = time.utcoffset()
return datetime.__new__(cls, tzinfo=GenericTZ(tzOffset),
*timeValues)
elif time is None:
print "Still gotta figure out now to do this one..."
else:
raise Invalidtime(time)
@staticmethod
def stringToTimeTuple(timeString):
... regex that parses timeString ...
>GeneralizedTime.today()
2006 (11, 16, 0, 35, 18, 747275, None) {}
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "gentime.py", line 106, in __new__
raise InvalidTime(time)
gentime.InvalidTime: 2006

So it appears the time tuple is being passed to
GeneralizedTime.__new__, but the first value is being assigned to the
"time" argument.

Is this a side effect of how datetime is implemented? Or am I doing
something screwy?

Thanks!

-Ben
A very cutback part of your code gets the basics working:
from datetime import datetime
class Invalidtime(Exception):
pass

class GeneralizedTime(datetime):
def __new__(cls, *args, **kwargs):
if isinstance(args, tuple):
return datetime.__new__(cls, *args)
else:
raise Invalidtime(args)

t = GeneralizedTime.today()
print t.year
print t.month
print t.day
print t.hour
print t.minute
print t.second
print t.microsecond
print t.tzinfo

Nov 16 '06 #2

P: n/a
in****@gmail.com wrote:
With assistance from Gabriel and Frederik (and a few old threads in
c.l.p.) I've been making headway on my specialized datetime class. Now
I'm puzzled by behavior I didn't expect while attempting to use some of
the alternate datetime constructors. Specifically, it appears if I
call GeneralizedTime.now() it calls the __new__ method of my class but
treats keyword arguments as if they were positional.

My class:

class GeneralizedTime(datetime):
def __new__(cls, time=None, *args, **kwargs):
print time, args, kwargs
if isinstance(time, str):
timeValues, tzOffset = cls.stringToTimeTuple(time)
return datetime.__new__(cls, tzinfo=GenericTZ(tzOffset),
**timeValues)
elif isinstance(time, datetime):
timeValues = time.timetuple()[:6]
tzOffset = time.utcoffset()
return datetime.__new__(cls, tzinfo=GenericTZ(tzOffset),
*timeValues)
elif time is None:
print "Still gotta figure out now to do this one..."
else:
raise Invalidtime(time)
@staticmethod
def stringToTimeTuple(timeString):
... regex that parses timeString ...
>>>GeneralizedTime.today()
2006 (11, 16, 0, 35, 18, 747275, None) {}
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "gentime.py", line 106, in __new__
raise InvalidTime(time)
gentime.InvalidTime: 2006

So it appears the time tuple is being passed to
GeneralizedTime.__new__, but the first value is being assigned to the
"time" argument.

Is this a side effect of how datetime is implemented?
Yes. Consider:
>>def today(time=None, *args):
.... print "time = ", time, "args = ", args
....
>>today(2006, 11, 16)
time = 2006 args = (11, 16)

To fix the issue you'll probably have to remove the time=None parameter from
GeneralizedTime.__new__() and instead extract it from args or kwargs.

Peter

Nov 16 '06 #3

P: n/a
Yes. Consider:
>
>def today(time=None, *args):
... print "time = ", time, "args = ", args
...
>today(2006, 11, 16)
time = 2006 args = (11, 16)

To fix the issue you'll probably have to remove the time=None parameter from
GeneralizedTime.__new__() and instead extract it from args or kwargs.
D'oh. That *should* have been obvious.

I am now no longer allowed to program after midnight.

Thanks!

-Ben

Nov 16 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.