Returning same type as self for arithmetic in subclasses

M

Max M

# -*- coding: latin-1 -*-


"""
I subclass datetime and timedelta
<class 'dtime.myTimedelta'>

But when I do arithmetic with these classes, they return datetime and
timedelta,
where I want them to return myDatetime and myTimedelta
datetime.datetime(1970, 1, 1, 1, 0)
<type 'datetime.datetime'>

So I wondered if there was a simlpler way to coerce the result into my
desired
types rather than overwriting the __add__, __sub__ etc. methods?

"""

from datetime import datetime, timedelta

class myDatetime(datetime):
pass

class myTimedelta(timedelta):
pass


if __name__ == "__main__":

import os.path, doctest, dtime
# import and test this file
doctest.testmod(dtime)




--

hilsen/regards Max M, Denmark

http://www.mxm.dk/
IT's Mad Science
 
T

Tim Peters

[Max M]
"""
I subclass datetime and timedelta

<class 'dtime.myTimedelta'>

But when I do arithmetic with these classes, they return datetime and
timedelta, ....
datetime.datetime(1970, 1, 1, 1, 0)

<type 'datetime.datetime'>

Yes, and all builtin Python types work that way. For example,
int.__add__ or float.__add__ applied to a subclass of int or float
will return an int or float; similarly for a subclass of str. This
was Guido's decision, based on that an implementation of any method in
a base class has no idea what requirements may exist for invoking a
subclass's constructor. For example, a subclass may restrict the
values of constructor arguments, or require more arguments than a base
class constructor; it may permute the order of positional arguments in
the base class constructor; it may even be "a feature" that a subclass
constructor gives a different meaning to an argument it shares with
the base class constructor. Since there isn't a way to guess, Python
does a safe thing instead.
where I want them to return myDatetime and myTimedelta

So I wondered if there was a simlpler way to coerce the result into my
desired types rather than overwriting the __add__, __sub__ etc. methods?

Generally speaking, no. But I'm sure someone will torture you with a
framework that purports to make it easy <wink>.
 
M

Max M

Tim said:
Yes, and all builtin Python types work that way. For example,
int.__add__ or float.__add__ applied to a subclass of int or float
will return an int or float; similarly for a subclass of str. This
was Guido's decision...

I will not discuss it with him. He is usually right :-s

Generally speaking, no. But I'm sure someone will torture you with a
framework that purports to make it easy <wink>.

Apparently not... But here is my solution.

If anybody is interrested. It should also be obvious what I am working on.

Btw. I really love doctests ... Unittests are a nice idea. But doctest
is a really practical solution.

###############################

class vDatetime(datetime):
"""
A subclass of datetime, that renders itself in the iCalendar datetime
format.
'19700101T123000'
'PT12H30M'

Adding is not allowed Traceback (most recent call last):
...
AttributeError: 'NotImplementedType' object has no attribute 'days'
"""

def __init__(self, *args, **kwargs):
datetime.__init__(self, *args, **kwargs)
self.params = Params()

def __add__(self, other):
return self._to_vdatetime(datetime.__add__(self, other))

def __sub__(self, other):
return self._to_vdatetime(datetime.__sub__(self, other))

def _to_vdatetime(self, result):
if hasattr(result, 'timetuple'):
return vDatetime(*result.timetuple()[:6])
return vDuration(result.days, result.seconds)

def fromstring(st):
"Class method that parses"
try:
timetuple = map(int, ((
st[:4], # year
st[4:6], # month
st[6:8], # day
st[9:11], # hour
st[11:13], # minute
st[13:15], # second
)))
except:
raise ValueError, 'Wrong format'
return vDatetime(*timetuple)
fromstring = staticmethod(fromstring)

def __str__(self):
return self.strftime("%Y%m%dT%H%M%S")



--

hilsen/regards Max M, Denmark

http://www.mxm.dk/
IT's Mad Science
 
S

Steve Holden

Tim said:
[Max M]
"""
I subclass datetime and timedelta
[...]

Generally speaking, no. But I'm sure someone will torture you with a
framework that purports to make it easy <wink>.

Clearly the easy way is to have the type declaration introspect on the
definitions of datetime and timedelta and then auto-create methods
wrapping the base types' methods in a "myxxx" conversion.

left-as-an-exercise-for-the-reader-ly y'rs - steve
 
M

michele.simionato

Max. M.:
So I wondered if there was a simlpler way to coerce the result into my
desired types rather than overwriting the __add__, __sub__ etc.
methods?

Tim Peters:
I will not dispute the Timbot assessment ;) He is also right that
people have
already undergone under this level of torture: see
http://tinyurl.com/6m373
for instance.

Michele Simionato
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top