__cmp__ between dissimilar objects

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • insyte@gmail.com

    #1

    __cmp__ between dissimilar objects

    I have a class that has, as an attribute, an instance of
    datetime.dateti me(). I would like to be able to compare my class
    directly to instances of datetime.dateti me in addition to other
    instances of my class. The value used for the comparison in either
    case should be the value of the datetime attribute of the class:

    from datetime import datetime

    class GeneralizedTime (object):
    def __init__(self, time=None):
    if time is None:
    self.datetime = datetime.now()
    def __cmp__(self, x):
    if isinstance(x, GeneralizedTime ):
    return cmp(self.dateti me, x.datetime)
    if isinstance(x, datetime):
    return cmp(self.dateti me, x)

    >>import datetime
    >>>
    >>GeneralizedTi me() datetime.now()
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    TypeError: can't compare datetime.dateti me to GeneralizedTime

    Clearly I'm misunderstandin g something, here. As I understand my code,
    I'm directly comparing an instance of datetime (self.datetime) to
    another instance of datetime.

    What am I failing to grasp?

    Thanks!

    -Ben

  • Gabriel Genellina

    #2
    Re: __cmp__ between dissimilar objects

    At Monday 13/11/2006 21:33, insyte@gmail.co m wrote:
    >I have a class that has, as an attribute, an instance of
    >datetime.datet ime(). I would like to be able to compare my class
    >directly to instances of datetime.dateti me in addition to other
    >instances of my class. The value used for the comparison in either
    >case should be the value of the datetime attribute of the class:
    >
    >from datetime import datetime
    >
    >class GeneralizedTime (object):
    def __init__(self, time=None):
    if time is None:
    self.datetime = datetime.now()
    def __cmp__(self, x):
    if isinstance(x, GeneralizedTime ):
    return cmp(self.dateti me, x.datetime)
    if isinstance(x, datetime):
    return cmp(self.dateti me, x)
    >
    >
    >import datetime
    >>
    >GeneralizedTim e() datetime.now()
    >Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    >TypeError: can't compare datetime.dateti me to GeneralizedTime
    This appears to be some braindead code in the datetime class.
    You have to provide all the "rich-comparison" methods, and even then,
    will never work when a datetime instance is at the left of the comparison.

    def __lt__(self, other): return self.__cmp__(ot her)<0
    def __le__(self, other): return self.__cmp__(ot her)<=0
    def __gt__(self, other): return self.__cmp__(ot her)>0
    def __ge__(self, other): return self.__cmp__(ot her)>=0
    def __eq__(self, other): return self.__cmp__(ot her)==0
    def __ne__(self, other): return self.__cmp__(ot her)!=0

    When the rich comparison methods raise NotImplementedE rror, the
    comparison logic inside the interpreter tries reversing the operands.
    But datetime objects don't do that, they raise TypeError, thus
    preventing the operand reversing. So any comparison with datetime on
    the left and your GeneralizedTime on the right side will fail.
    If nobody has an explanation on *why* datetime does this, I'd say it's a bug.


    --
    Gabriel Genellina
    Softlab SRL

    _______________ _______________ _______________ _____
    Correo Yahoo!
    Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
    ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar

    Comment

    • Fredrik Lundh

      #3
      Re: __cmp__ between dissimilar objects

      insyte@gmail.co m wrote:
      >I have a class that has, as an attribute, an instance of
      datetime.dateti me(). I would like to be able to compare my class
      directly to instances of datetime.dateti me in addition to other
      instances of my class. The value used for the comparison in either
      case should be the value of the datetime attribute of the class:
      >
      from datetime import datetime
      >
      class GeneralizedTime (object):
      def __init__(self, time=None):
      if time is None:
      self.datetime = datetime.now()
      def __cmp__(self, x):
      if isinstance(x, GeneralizedTime ):
      return cmp(self.dateti me, x.datetime)
      if isinstance(x, datetime):
      return cmp(self.dateti me, x)
      >
      >>>import datetime
      >>>>
      >>>GeneralizedT ime() datetime.now()
      Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      TypeError: can't compare datetime.dateti me to GeneralizedTime
      >
      Clearly I'm misunderstandin g something, here. As I understand my code,
      I'm directly comparing an instance of datetime (self.datetime) to
      another instance of datetime.
      sure looks like you're comparing a datetime instance against a GeneralizeTime
      instance to me.

      why not just inherit from datetime instead? or read footnote 4 under "supported
      operations" on this page for info on how to implement mixed-type comparisions:



      </F>



      Comment

      • insyte@gmail.com

        #4
        Re: __cmp__ between dissimilar objects

        why not just inherit from datetime instead?

        I'll probably do that in the next iteration.
        or read footnote 4 under "supported operations" on this page for info on how to
        implement mixed-type comparisions:
        >
        http://docs.python.org/lib/datetime-datetime.html
        OK. I added a 'timetuple' attribute to my class. Now comparisons seem
        to "just work". This has made it even more obvious to me that I don't
        understand how comparisons function:

        If the GeneralizedTime instance is on the LHS of the comparison and the
        datetime instance on the RHS, why would datetime's __cmp__ method be
        called? I assume its being called since GeneralizedTime sure doesn't
        care whether or not it has a timetuple attribute...

        I've read through the "Basic customization" section of the language
        reference, which doesn't seem to describe a scenario where the __cmp__
        method on the RHS is called.

        Thanks...

        -Ben

        Comment

        • insyte@gmail.com

          #5
          Re: __cmp__ between dissimilar objects

          When the rich comparison methods raise NotImplementedE rror, the
          comparison logic inside the interpreter tries reversing the operands.
          Can you point me to a description of this algorithm? It doesn't seem
          to be described in the documentation for the rich comparison or __cmp__
          methods...

          -Ben

          Comment

          • Gabriel Genellina

            #6
            Re: __cmp__ between dissimilar objects

            At Tuesday 14/11/2006 13:41, insyte@gmail.co m wrote:
            When the rich comparison methods raise NotImplementedE rror, the
            comparison logic inside the interpreter tries reversing the operands.
            >
            >Can you point me to a description of this algorithm? It doesn't seem
            >to be described in the documentation for the rich comparison or __cmp__
            >methods...
            PEP 207



            --
            Gabriel Genellina
            Softlab SRL

            _______________ _______________ _______________ _____
            Correo Yahoo!
            Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
            ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar

            Comment

            • Gabriel Genellina

              #7
              Re: __cmp__ between dissimilar objects

              At Tuesday 14/11/2006 09:33, Fredrik Lundh wrote:
              >>GeneralizedTi me() datetime.now()
              Traceback (most recent call last):
              File "<stdin>", line 1, in ?
              TypeError: can't compare datetime.dateti me to GeneralizedTime

              Clearly I'm misunderstandin g something, here. As I understand my code,
              I'm directly comparing an instance of datetime (self.datetime) to
              another instance of datetime.
              >
              >sure looks like you're comparing a datetime instance against a GeneralizeTime
              >instance to me.
              >
              >why not just inherit from datetime instead? or read footnote 4
              >under "supported
              >operations" on this page for info on how to implement mixed-type comparisions:
              >
              http://docs.python.org/lib/datetime-datetime.html
              Ugh... I hope there were good reasons for doing things so convoluted...


              --
              Gabriel Genellina
              Softlab SRL

              _______________ _______________ _______________ _____
              Correo Yahoo!
              Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
              ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar

              Comment

              • insyte@gmail.com

                #8
                Re: __cmp__ between dissimilar objects

                Can you point me to a description of this algorithm? It doesn't seem
                to be described in the documentation for the rich comparison or __cmp__
                methods...
                >
                PEP 207
                http://www.python.org/dev/peps/pep-0207/
                So since I implemented __cmp__ instead of the rich comparison
                operators, Python first tried to reverse the comparison. This gave
                datetime the opportunity to throw TypeError *before* the interpreter
                failed over to trying __cmp__.

                Is that correct?

                Thanks!

                -Ben

                Comment

                • Gabriel Genellina

                  #9
                  Re: __cmp__ between dissimilar objects

                  At Tuesday 14/11/2006 19:27, insyte@gmail.co m wrote:
                  >Can you point me to a description of this algorithm? It doesn't seem
                  >to be described in the documentation for the rich comparison or __cmp__
                  >methods...
                  PEP 207
                  http://www.python.org/dev/peps/pep-0207/
                  >
                  >So since I implemented __cmp__ instead of the rich comparison
                  >operators, Python first tried to reverse the comparison. This gave
                  >datetime the opportunity to throw TypeError *before* the interpreter
                  >failed over to trying __cmp__.
                  >
                  >Is that correct?
                  Exactly. And if datetime were not so special in its implementation, a
                  NotImplementedE rror (instead of TypeError) would have let your code a
                  chance of being executed.


                  --
                  Gabriel Genellina
                  Softlab SRL

                  _______________ _______________ _______________ _____
                  Correo Yahoo!
                  Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
                  ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar

                  Comment

                  Working...