On Aug 15, 5:54 pm, "Colin J. Williams" <[EMAIL PROTECTED]> 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 -- http://mail.python.org/mailman/listinfo/python-list