sub-classing the types in the builtin module datetime
Colin J. Williams
cjw at sympatico.ca
Thu Aug 16 17:33:43 EDT 2007
attn.steven.kuo at gmail.com wrote:
> On Aug 15, 5:54 pm, "Colin J. Williams" <c... at sympatico.ca> wrote:
>> I posted this about 5 hours ago, but it seems to have gone astray.
>
>
> (snipped)
>
>> >
>> >> I wish to sub-class (if that's the right word) datetime and to use a
>> >> different signature for the constructor.
>> >>
>> >> The second part has gone smoothly, but it is difficult to access the
>> >> type's methods from the sub-class instance.
>> >>
>> >> I'm beginning to wonder whether it might might be simpler to write my
>> >> own Date class.
>> >>
>> >> Does anyone have any comments please?
>> >>
>> >> Colin W.
>
> (snipped)
>
>
>> Yes, I should have posted an example, but I thought that others might
>> have experienced the problem.
>>
>> It is illustrated at the bottom of this script:
>>
>> # subClassing.py
>>
>> import datetime
>> import new
>> import sys
>> import types
>>
>> class Date(datetime.datetime):
>> ''' Date(s) -> a date object.__class__
>> where s is an 8 digit string'''
>>
>> def __new__(cls, YYmmdd):
>> ''' YYmmdd is a string, in the form yyyymmdd i.e. 8 digits.
>> or a 3-tuple of integers in the form (y, m, d)
>> or a 6-tuple of integers in the form (y, m, d, h, m,
>> s) '''
>
>
> (snipped)
>
>> a= datetime.datetime(2007, 7, 31)
>> d= Date('20070731')
>> tm= datetime.time(1, 2)
>> try:
>> print a.today()
>> # print d.today() # grief
>> print a.now()
>> # print d.now() # grief
>> print a.combine(a, tm) # OK, but why not a.combine(tm)?
>> # e= d.combine(d, tm) # grief
>> print a.utcnow()
>> # print d.utcnow() # grief
>> print a.ctime()
>> print d.ctime()
>> except:
>> print 'Grief'
>> print sys.exc_info()
>>
>> Colin W.
>
>
>
>
>
> This problem arises when you change the function signature of __new__.
> I'm a little unclear as to why but it seems for the classmethods
> (thosed marked with the METH_CLASS flag in the C source code), you
> need to arrange to bypass the normal method resolution (I used a
> metaclass
> to do this):
>
>
>
> import datetime
>
> class Date(datetime.datetime):
> pass
>
> class FixClassMethods(type):
> def __init__(cls, classname, bases, classdict):
> # add strptime if using Python 2.5
> flagged_as_meth_class = ('today', 'now', 'fromtimestamp',
> 'fromordinal', 'now', 'utcnow', 'utcfromtimestamp', 'combine')
> for meth in flagged_as_meth_class:
> setattr(cls, meth, getattr(datetime.datetime, meth))
>
> class DateChangesNewSignature(datetime.datetime):
> @staticmethod
> def str2ymd(strval):
> yyyy, mm, dd = (int(substr) for substr in (strval[:4],
> strval[4:6], strval[6:]))
> return yyyy, mm, dd
>
> def __new__(cls, strval):
> yyyy, mm, dd = DateChangesNewSignature.str2ymd(strval)
> return super(DateChangesNewSignature,cls).__new__(cls, yyyy,
> mm,
> dd)
> def __init__(self, strval):
> yyyy, mm, dd = DateChangesNewSignature.str2ymd(strval)
> super(DateChangesNewSignature, self).__init__(yyyy, mm,
> dd)
>
> class DLast(DateChangesNewSignature):
> __metaclass__ = FixClassMethods
>
> f = Date(2007,07,07)
> print f
> print f.today()
>
> f2 = DateChangesNewSignature("20070707")
> print f2
> try:
> print f2.today()
> except TypeError, e:
> print str(e)
> print "Uh?"
>
>
> f3 = DLast("20070707")
> print f3
> print f3.today()
>
>
> I get:
>
> 2007-07-07 00:00:00
> 2007-08-16 12:57:41.480679
> 2007-07-07 00:00:00
> __new__() takes exactly 2 arguments (9 given)
> Uh?
> 2007-07-07 00:00:00
> 2007-08-16 12:57:41.483104
>
>
> --
> Hope this helps,
> Steven
>
Steven,
Many thanks, I'll try this out tomorrow.
Colin W
More information about the Python-list
mailing list