Returning same type as self for arithmetic in subclasses

Discussion in 'Python' started by Max M, Jan 7, 2005.

  1. Max M

    Max M Guest

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


    """
    I subclass datetime and timedelta

    >>> dt = myDatetime(1970,1,1)
    >>> type(dt)

    <class 'dtime.myDatetime'>

    >>> td = myTimedelta(hours=1)
    >>> type(td)

    <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

    >>> new_time = dt + td
    >>> new_time

    datetime.datetime(1970, 1, 1, 1, 0)

    >>> type(new_time)

    <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
     
    Max M, Jan 7, 2005
    #1
    1. Advertising

  2. Max M

    Tim Peters Guest

    [Max M]
    > """
    > I subclass datetime and timedelta
    >
    > >>> dt = myDatetime(1970,1,1)
    > >>> type(dt)

    > <class 'dtime.myDatetime'>
    >
    > >>> td = myTimedelta(hours=1)
    > >>> type(td)

    > <class 'dtime.myTimedelta'>
    >
    > But when I do arithmetic with these classes, they return datetime and
    > timedelta,

    ....
    > >>> new_time = dt + td
    > >>> new_time

    > datetime.datetime(1970, 1, 1, 1, 0)
    >
    > >>> type(new_time)

    > <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>.
     
    Tim Peters, Jan 8, 2005
    #2
    1. Advertising

  3. Max M

    Max M Guest

    Tim Peters wrote:

    > 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.

    >>> dt = vDatetime(1970, 1,1, 12, 30, 0)
    >>> str(dt)

    '19700101T123000'

    >>> dt2 = vDatetime(1970, 1,1, 0, 0, 0)
    >>> str(dt - dt2)

    'PT12H30M'

    Adding is not allowed
    >>> dt + dt2

    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
     
    Max M, Jan 8, 2005
    #3
  4. Max M

    Steve Holden Guest

    Tim Peters wrote:

    > [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
    --
    Steve Holden http://www.holdenweb.com/
    Python Web Programming http://pydish.holdenweb.com/
    Holden Web LLC +1 703 861 4237 +1 800 494 3119
     
    Steve Holden, Jan 8, 2005
    #4
  5. Max M

    Guest

    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:
    >> Generally speaking, no. But I'm sure someone will torture you with a
    >> framework that purports to make it easy <wink>.


    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
     
    , Jan 9, 2005
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ralf W. Grosse-Kunstleve
    Replies:
    16
    Views:
    586
    Lonnie Princehouse
    Jul 11, 2005
  2. Ralf W. Grosse-Kunstleve
    Replies:
    18
    Views:
    599
    Bengt Richter
    Jul 11, 2005
  3. Ralf W. Grosse-Kunstleve
    Replies:
    2
    Views:
    404
    Dan Sommers
    Jul 12, 2005
  4. falcon
    Replies:
    0
    Views:
    379
    falcon
    Jul 31, 2005
  5. Bart Kastermans
    Replies:
    6
    Views:
    407
    Bart Kastermans
    Jul 13, 2008
Loading...

Share This Page