sub-classing the types in the builtin module datetime

Colin J. Williams cjw at sympatico.ca
Fri Aug 17 23:32:09 CEST 2007


attn.steven.kuo at gmail.com wrote:
[My question snipped]
> 
> 
> 
> 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,

Thanks, you provide an elegant solution to the datetime problem I raised.

I like the illustration of metaclass usage you have have given,
it's something I have had trouble grasping.

You handle the examples I gave.  However, on reflection,I feel that
('today', 'now', 'fromtimestamp', 'fromordinal', 'now', 'utcnow', 
'utcfromtimestamp', 'combine') are completely inappropriate as
methods and that they should have been set up as functions of
datetime and not as methods of datetime.datetime.
The difficulty I have in adopting your approach is that it would
be difficult for the reader to comprehend the code.

My feeling is that it should be possible to change a signature using
simple Python approaches.

I'll puzzle some more.

Thanks again.

Colin W.




More information about the Python-list mailing list