[EMAIL PROTECTED] wrote: > 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 > Steven,
Many thanks, I'll try this out tomorrow. Colin W -- http://mail.python.org/mailman/listinfo/python-list