Overloading ctor doesn't work?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Martin Häcker

    #1

    Overloading ctor doesn't work?

    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.TestC ase):
    def testSmoke(self) :
    # print time() # bombs, and complains that
    # the time ctor needs at least 3 arguments
    self.assertEqua ls(datetime(1,1 ,1,1,2,3,4),tim e(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
  • Steve Holden

    #2
    Re: Overloading ctor doesn't work?

    Martin Häcker wrote:
    [color=blue]
    > 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.TestC ase):
    > def testSmoke(self) :
    > # print time() # bombs, and complains that
    > # the time ctor needs at least 3 arguments
    > self.assertEqua ls(datetime(1,1 ,1,1,2,3,4),tim e(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?
    >[/color]
    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

    Comment

    • Kent Johnson

      #3
      Re: Overloading ctor doesn't work?

      > Martin Häcker wrote:[color=blue]
      >[color=green]
      >> 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?[/color][/color]

      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

      Comment

      • Francis Girard

        #4
        Re: Overloading ctor doesn't work?

        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 :[color=blue]
        > 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.TestC ase):
        > def testSmoke(self) :
        > # print time() # bombs, and complains that
        > # the time ctor needs at least 3 arguments
        > self.assertEqua ls(datetime(1,1 ,1,1,2,3,4),tim e(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[/color]

        Comment

        • Francis Girard

          #5
          Re: Overloading ctor doesn't work?

          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 :[color=blue][color=green]
          > > Martin Häcker wrote:[color=darkred]
          > >> 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?[/color][/color]
          >
          > 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[/color]

          Comment

          • Paul McGuire

            #6
            Re: Overloading ctor doesn't work?

            "Kent Johnson" <kent3737@yahoo .com> wrote in message
            news:41effd30$1 _1@newspeer2.td s.net...[color=blue][color=green]
            > > Martin Häcker wrote:
            > >[color=darkred]
            > >> 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?[/color][/color]
            >
            > 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,[/color]
            microseconds)[color=blue]
            >
            > print time(1,2,3,4) # => 0001-02-03 04:00:00
            > print time() # => TypeError: function takes at least 3 arguments (0[/color]
            given)[color=blue]
            >
            >
            > What happens to the default arguments to time.__init__? What happens to[/color]
            the 2001, 10, 31 arguments[color=blue]
            > 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[/color]

            I can't explain this behavior, but this version does work (uses
            datetime.combin e 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.combin e(tmpdate, dt_time(h,mi,s, ms))
            elif len(args)==7:
            y,m,d,h,mi,s,ms = args
            return datetime.combin e(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)



            Comment

            • Kent Johnson

              #7
              Re: Overloading ctor doesn't work?

              Paul McGuire wrote:[color=blue]
              > "Kent Johnson" <kent3737@yahoo .com> wrote in message
              > news:41effd30$1 _1@newspeer2.td s.net...
              >[color=green][color=darkred]
              >>>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?[/color]
              >>
              >>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,[/color]
              >
              > microseconds)
              >[color=green]
              >>print time(1,2,3,4) # => 0001-02-03 04:00:00
              >>print time() # => TypeError: function takes at least 3 arguments (0[/color]
              >
              > given)
              >[color=green]
              >>
              >>What happens to the default arguments to time.__init__? What happens to[/color]
              >
              > the 2001, 10, 31 arguments
              >[color=green]
              >>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[/color]
              >
              >
              > I can't explain this behavior, but this version does work (uses
              > datetime.combin e 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.combin e(tmpdate, dt_time(h,mi,s, ms))
              > elif len(args)==7:
              > y,m,d,h,mi,s,ms = args
              > return datetime.combin e(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)[/color]


              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.


              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
              [color=blue]
              >
              >
              >[/color]

              Comment

              • Martin Häcker

                #8
                Re: Overloading ctor doesn't work?

                > Ah, right. The light turns on...[color=blue]
                >
                > 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__[/color]

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

                Thanks again!
                cu Martin

                --
                Reach me at spamfaenger (at) gmx (dot) net

                Comment

                • Nick Craig-Wood

                  #9
                  Re: Overloading ctor doesn't work?

                  Martin Häcker <dwt23@hotmail. com> wrote:[color=blue]
                  > 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?[/color]

                  Its a bug!

                  http://sourceforge.net/tracker/index...70&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 <nick@craig-wood.com> -- http://www.craig-wood.com/nick

                  Comment

                  • Kent Johnson

                    #10
                    Re: Overloading ctor doesn't work?

                    Nick Craig-Wood wrote:[color=blue]
                    > Martin Häcker <dwt23@hotmail. com> wrote:
                    >[color=green]
                    >> 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. :([/color]
                    >
                    > Its a bug!
                    >
                    > http://sourceforge.net/tracker/index...70&atid=105470
                    >
                    > However its been fixed in a recent Python 2.3.[/color]

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

                    Kent
                    [color=blue]
                    >
                    > (I was bitten by the same thing which used to fail but now works after
                    > an upgrade of python 2.3!)[/color]

                    Comment

                    Working...