I recently ran into a situatiton where I needed to subclass datetime.datetime and datetime.timedelta in order to add a few methods. I immediately found, though, that any arithmetic operations would return a datetime.datetime object when I expected it to return a mydatetime.mydatetime instance instead. Below is the solution that a co-worker helped me out with for this problem. Does anyone have a more concise or convenient suggestion? Are there any dangers to what I have done here? Am I missing anything important?
from datetime import datetime, timedelta
def _to_mydatetime(native):
'''Instantiates object of appropriate class based on class
of the input object.'''
if hasattr(native, 'timetuple'):
return mydatetime(*native.timetuple()[:6])
else:
return mytimedelta(native.days, native.seconds)
class mydatetime(datetime):
'''Subclass of datetime'''
def __add__(self, other):
result = super(mydatetime, self).__add__(other)
return _to_mydatetime(result)
def __sub__(self, other):
result = super(mydatetime, self).__sub__(other)
return _to_mydatetime(result)
class mytimedelta(timedelta):
def __add__(self, other):
result = super(mytimedelta, self).__add__(other)
return _to_mydatetime(result)
def __sub__(self, other):
result = super(mytimedelta, self).__sub__(other)
return _to_mydatetime(result)
def __div__(self, other):
result = super(mytimedelta, self).__div__(other)
return _to_mydatetime(result)
def __rmul__(self, other):
result = super(mytimedelta, self).__rmul__(other)
return _to_mydatetime(result)
def __mul__(self, other):
result = super(mytimedelta, self).__mul__(other)
return _to_mydatetime(result)
Well, this is the right way to do it (i’d just split the converter method into two). Python allows you to reduce code duplication though:
The cryptic code under
convproxyis just a smart-aleck way to generate the specified methods when creating a class, each of which calls a superclass method and creates a subclass from the result using the specified converter function.