Overloading ctor doesn't work?

Discussion in 'Python' started by =?ISO-8859-1?Q?Martin_H=E4cker?=, Jan 20, 2005.

  1. Hi there,

    I just tried to run this code and failed miserably - though I dunno why.
    Could any of you please enlighten me why this doesn't work?

    Thanks a bunch.

    --- snip ---
    import unittest
    from datetime import datetime

    class time (datetime):
    def __init__(self, hours=0, minutes=0, seconds=0, microseconds=0):
    print "blah"
    datetime.__init__(self, 1, 1, 1, hours, \
    minutes, seconds, microseconds)


    class Test (unittest.TestCase):
    def testSmoke(self):
    # print time() # bombs, and complains that
    # the time ctor needs at least 3 arguments
    self.assertEquals(datetime(1,1,1,1,2,3,4),time(1,2,3,4))


    if __name__ == '__main__':
    unittest.main()
    --- snap ---

    The reason I want to do this is that I want to work with times but I
    want to do arithmetic with them. Therefore I cannot use the provided
    time directly.

    Now I thought, just overide the ctor of datetime so that year, month and
    day are static and everything should work as far as I need it.

    That is, it could work - though I seem to be unable to overide the ctor. :(

    Why is that?

    cu Martin

    --
    Reach me at spamfaenger (at) gmx (dot) net
    =?ISO-8859-1?Q?Martin_H=E4cker?=, Jan 20, 2005
    #1
    1. Advertising

  2. =?ISO-8859-1?Q?Martin_H=E4cker?=

    Steve Holden Guest

    Martin Häcker wrote:

    > Hi there,
    >
    > I just tried to run this code and failed miserably - though I dunno why.
    > Could any of you please enlighten me why this doesn't work?
    >
    > Thanks a bunch.
    >
    > --- snip ---
    > import unittest
    > from datetime import datetime
    >
    > class time (datetime):
    > def __init__(self, hours=0, minutes=0, seconds=0, microseconds=0):
    > print "blah"
    > datetime.__init__(self, 1, 1, 1, hours, \
    > minutes, seconds, microseconds)
    >
    >
    > class Test (unittest.TestCase):
    > def testSmoke(self):
    > # print time() # bombs, and complains that
    > # the time ctor needs at least 3 arguments
    > self.assertEquals(datetime(1,1,1,1,2,3,4),time(1,2,3,4))
    >
    >
    > if __name__ == '__main__':
    > unittest.main()
    > --- snap ---
    >
    > The reason I want to do this is that I want to work with times but I
    > want to do arithmetic with them. Therefore I cannot use the provided
    > time directly.
    >
    > Now I thought, just overide the ctor of datetime so that year, month and
    > day are static and everything should work as far as I need it.
    >
    > That is, it could work - though I seem to be unable to overide the ctor. :(
    >
    > Why is that?
    >

    Perhpas the error message or output, which you don't provide, would
    avoid our having to use our psychic powers? ;-)

    In other words: what's wrong? How do you *know* you can't override it?

    regards
    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 20, 2005
    #2
    1. Advertising

  3. =?ISO-8859-1?Q?Martin_H=E4cker?=

    Kent Johnson Guest

    > Martin Häcker wrote:
    >
    >> Hi there,
    >>
    >> I just tried to run this code and failed miserably - though I dunno
    >> why. Could any of you please enlighten me why this doesn't work?


    Here is a simpler test case. I'm mystified too:

    from datetime import datetime

    class time (datetime):
    def __init__(self, hours=0, minutes=0, seconds=0, microseconds=0):
    datetime.__init__(self, 2001, 10, 31, hours, minutes, seconds, microseconds)

    print time(1,2,3,4) # => 0001-02-03 04:00:00
    print time() # => TypeError: function takes at least 3 arguments (0 given)


    What happens to the default arguments to time.__init__? What happens to the 2001, 10, 31 arguments
    to datetime.__init__?

    I would expect the output to be
    2001-10-31 01:02:03.000004
    2001-10-31 00:00:00.000000

    Kent
    Kent Johnson, Jan 20, 2005
    #3
  4. Hi,

    It looks like the assertEquals use the != operator which had not been defined
    to compare instances of your time class and instances of the datetime class.
    In such a case, the operator ends up in comparing the references to instances,
    i.e. the "id" of the objects, i.e. their physical memory addresses, which of
    course can't be the same. And that is why your test fails.

    Consider defining the __cmp__ method (see 2.3.3 Comparisons of the library
    reference). Sess also the operator module.

    Francis Girard
    LANNILIS
    Breizh
    FRANCE

    Le jeudi 20 Janvier 2005 19:23, Martin Häcker a écrit :
    > Hi there,
    >
    > I just tried to run this code and failed miserably - though I dunno why.
    > Could any of you please enlighten me why this doesn't work?
    >
    > Thanks a bunch.
    >
    > --- snip ---
    > import unittest
    > from datetime import datetime
    >
    > class time (datetime):
    > def __init__(self, hours=0, minutes=0, seconds=0, microseconds=0):
    > print "blah"
    > datetime.__init__(self, 1, 1, 1, hours, \
    > minutes, seconds, microseconds)
    >
    >
    > class Test (unittest.TestCase):
    > def testSmoke(self):
    > # print time() # bombs, and complains that
    > # the time ctor needs at least 3 arguments
    > self.assertEquals(datetime(1,1,1,1,2,3,4),time(1,2,3,4))
    >
    >
    > if __name__ == '__main__':
    > unittest.main()
    > --- snap ---
    >
    > The reason I want to do this is that I want to work with times but I
    > want to do arithmetic with them. Therefore I cannot use the provided
    > time directly.
    >
    > Now I thought, just overide the ctor of datetime so that year, month and
    > day are static and everything should work as far as I need it.
    >
    > That is, it could work - though I seem to be unable to overide the ctor. :(
    >
    > Why is that?
    >
    > cu Martin
    >
    > --
    > Reach me at spamfaenger (at) gmx (dot) net
    Francis Girard, Jan 20, 2005
    #4
  5. Wow !
    Now, this is serious. I tried all sort of things but can't solve the problem.
    I'm mystified too and forget my last reply.
    I'm curious to see the answers.
    Francis Girard
    Le jeudi 20 Janvier 2005 19:59, Kent Johnson a écrit :
    > > Martin Häcker wrote:
    > >> Hi there,
    > >>
    > >> I just tried to run this code and failed miserably - though I dunno
    > >> why. Could any of you please enlighten me why this doesn't work?

    >
    > Here is a simpler test case. I'm mystified too:
    >
    > from datetime import datetime
    >
    > class time (datetime):
    > def __init__(self, hours=0, minutes=0, seconds=0, microseconds=0):
    > datetime.__init__(self, 2001, 10, 31, hours, minutes, seconds,
    > microseconds)
    >
    > print time(1,2,3,4) # => 0001-02-03 04:00:00
    > print time() # => TypeError: function takes at least 3 arguments (0
    > given)
    >
    >
    > What happens to the default arguments to time.__init__? What happens to the
    > 2001, 10, 31 arguments to datetime.__init__?
    >
    > I would expect the output to be
    > 2001-10-31 01:02:03.000004
    > 2001-10-31 00:00:00.000000
    >
    > Kent
    Francis Girard, Jan 20, 2005
    #5
  6. =?ISO-8859-1?Q?Martin_H=E4cker?=

    Paul McGuire Guest

    "Kent Johnson" <> wrote in message
    news:41effd30$...
    > > Martin Häcker wrote:
    > >
    > >> Hi there,
    > >>
    > >> I just tried to run this code and failed miserably - though I dunno
    > >> why. Could any of you please enlighten me why this doesn't work?

    >
    > Here is a simpler test case. I'm mystified too:
    >
    > from datetime import datetime
    >
    > class time (datetime):
    > def __init__(self, hours=0, minutes=0, seconds=0, microseconds=0):
    > datetime.__init__(self, 2001, 10, 31, hours, minutes, seconds,

    microseconds)
    >
    > print time(1,2,3,4) # => 0001-02-03 04:00:00
    > print time() # => TypeError: function takes at least 3 arguments (0

    given)
    >
    >
    > What happens to the default arguments to time.__init__? What happens to

    the 2001, 10, 31 arguments
    > to datetime.__init__?
    >
    > I would expect the output to be
    > 2001-10-31 01:02:03.000004
    > 2001-10-31 00:00:00.000000
    >
    > Kent


    I can't explain this behavior, but this version does work (uses
    datetime.combine instead of ctor)

    -- Paul


    from datetime import datetime, date as dt_date, time as dt_time

    class time_d (datetime):
    def __new__(cls, *args):
    # default to no microseconds
    if len(args)==3:
    args = args + (0,)
    if len(args)==4:
    tmpdate = datetime.today()
    h, mi, s, ms = args
    return datetime.combine(tmpdate, dt_time(h,mi,s,ms))
    elif len(args)==7:
    y,m,d,h,mi,s,ms = args
    return datetime.combine(dt_date(y,m,d), dt_time(h,mi,s,ms))
    else:
    raise TypeError, "wrong number of args"

    print time_d(2001,10,31,1,2,3,4)
    print time_d(1,2,3,4)
    print time_d(1,2,3)
    Paul McGuire, Jan 20, 2005
    #6
  7. =?ISO-8859-1?Q?Martin_H=E4cker?=

    Kent Johnson Guest

    Paul McGuire wrote:
    > "Kent Johnson" <> wrote in message
    > news:41effd30$...
    >
    >>>Martin Häcker wrote:
    >>>
    >>>
    >>>>Hi there,
    >>>>
    >>>>I just tried to run this code and failed miserably - though I dunno
    >>>>why. Could any of you please enlighten me why this doesn't work?

    >>
    >>Here is a simpler test case. I'm mystified too:
    >>
    >>from datetime import datetime
    >>
    >>class time (datetime):
    >> def __init__(self, hours=0, minutes=0, seconds=0, microseconds=0):
    >> datetime.__init__(self, 2001, 10, 31, hours, minutes, seconds,

    >
    > microseconds)
    >
    >>print time(1,2,3,4) # => 0001-02-03 04:00:00
    >>print time() # => TypeError: function takes at least 3 arguments (0

    >
    > given)
    >
    >>
    >>What happens to the default arguments to time.__init__? What happens to

    >
    > the 2001, 10, 31 arguments
    >
    >>to datetime.__init__?
    >>
    >>I would expect the output to be
    >>2001-10-31 01:02:03.000004
    >>2001-10-31 00:00:00.000000
    >>
    >>Kent

    >
    >
    > I can't explain this behavior, but this version does work (uses
    > datetime.combine instead of ctor)
    >
    > -- Paul
    >
    >
    > from datetime import datetime, date as dt_date, time as dt_time
    >
    > class time_d (datetime):
    > def __new__(cls, *args):
    > # default to no microseconds
    > if len(args)==3:
    > args = args + (0,)
    > if len(args)==4:
    > tmpdate = datetime.today()
    > h, mi, s, ms = args
    > return datetime.combine(tmpdate, dt_time(h,mi,s,ms))
    > elif len(args)==7:
    > y,m,d,h,mi,s,ms = args
    > return datetime.combine(dt_date(y,m,d), dt_time(h,mi,s,ms))
    > else:
    > raise TypeError, "wrong number of args"
    >
    > print time_d(2001,10,31,1,2,3,4)
    > print time_d(1,2,3,4)
    > print time_d(1,2,3)



    Ah, right. The light turns on...

    datetime is immutable so overriding the constructor doesn't change the constructed object. You have
    to override __new__ instead.
    http://www.python.org/2.2.1/descrintro.html#__new__

    This works:

    from datetime import datetime

    class time (datetime):
    def __new__(cls, hours=0, minutes=0, seconds=0, microseconds=0):
    return datetime.__new__(cls, 2001, 10, 31, hours, minutes, seconds, microseconds)

    print time(1,2,3,4) # => 2001-10-31 01:02:03.000004
    print time() # => 2001-10-31 00:00:00

    Kent

    >
    >
    >
    Kent Johnson, Jan 20, 2005
    #7
  8. > Ah, right. The light turns on...
    >
    > datetime is immutable so overriding the constructor doesn't change the
    > constructed object. You have to override __new__ instead.
    > http://www.python.org/2.2.1/descrintro.html#__new__


    Ahhh! Thanks a bunch, now this makes things much clearer.

    Thanks again!
    cu Martin

    --
    Reach me at spamfaenger (at) gmx (dot) net
    =?ISO-8859-1?Q?Martin_H=E4cker?=, Jan 20, 2005
    #8
  9. Martin Häcker <> wrote:
    > Now I thought, just overide the ctor of datetime so that year, month and
    > day are static and everything should work as far as I need it.
    >
    > That is, it could work - though I seem to be unable to overide the ctor. :(
    >
    > Why is that?


    Its a bug!

    http://sourceforge.net/tracker/index.php?func=detail&aid=720908&group_id=5470&atid=105470

    However its been fixed in a recent Python 2.3.

    (I was bitten by the same thing which used to fail but now works after
    an upgrade of python 2.3!)
    --
    Nick Craig-Wood <> -- http://www.craig-wood.com/nick
    Nick Craig-Wood, Jan 21, 2005
    #9
  10. =?ISO-8859-1?Q?Martin_H=E4cker?=

    Kent Johnson Guest

    Nick Craig-Wood wrote:
    > Martin Häcker <> wrote:
    >
    >> Now I thought, just overide the ctor of datetime so that year, month and
    >> day are static and everything should work as far as I need it.
    >>
    >> That is, it could work - though I seem to be unable to overide the ctor. :(

    >
    > Its a bug!
    >
    > http://sourceforge.net/tracker/index.php?func=detail&aid=720908&group_id=5470&atid=105470
    >
    > However its been fixed in a recent Python 2.3.


    My example was developed in Python 2.4. The problem was the immutability of datetime.

    Kent

    >
    > (I was bitten by the same thing which used to fail but now works after
    > an upgrade of python 2.3!)
    Kent Johnson, Jan 21, 2005
    #10
    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. Apricot
    Replies:
    4
    Views:
    523
    velthuijsen
    Apr 16, 2004
  2. NVH
    Replies:
    8
    Views:
    485
    mlimber
    Jul 6, 2006
  3. Grizlyk
    Replies:
    8
    Views:
    481
    Grizlyk
    Nov 29, 2006
  4. , India

    copy ctor vs default ctor

    , India, Aug 15, 2007, in forum: C++
    Replies:
    2
    Views:
    405
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=
    Aug 15, 2007
  5. Anonymous
    Replies:
    2
    Views:
    375
    Victor Bazarov
    Aug 28, 2007
Loading...

Share This Page