[Python-3000] Trying to understand Python 3's comparisons
Mark Summerfield
mark at qtrac.eu
Wed Nov 21 09:19:50 CET 2007
On 2007-11-20, you wrote:
> (top-posting to shorten the reading time)
>
[snip]
> This does mean that it doesn't fall back on logical equivalences. It
> is entirely possible (though pathological) for two objects to be both
> equal and unequal, or for one to be both less-than the other but not
> less-than-or-equal.
Ah, this was the point I was missing. If you have < then you can define
all the other comparison in terms of it. Yet when you define < and ==
Python gives you > and != by reversing arguments, but doesn't give you
<= or >= even though it is possible to do so.
I'll write myself a class decorator that can create the "missing"
comparisons using logical equivalences.
Thanks!
> -jJ
>
> On 11/16/07, Mark Summerfield <mark at qtrac.eu> wrote:
> > Hi,
> >
> > I'm trying to understand Python 3's comparisons.
> >
> > class Eq:
> > def __init__(self, x=""):
> > self.x = x
> > def __str__(self):
> > return self.x
> > def __eq__(self, other):
> > return str(self) == str(other)
> >
> > class Lt:
> > def __init__(self, x=""):
> > self.x = x
> > def __str__(self):
> > return self.x
> > def __lt__(self, other):
> > return str(self) < str(other)
> >
> > class LtEq:
> > def __init__(self, x=""):
> > self.x = x
> > def __str__(self):
> > return self.x
> > def __eq__(self, other):
> > return str(self) == str(other)
> > def __lt__(self, other):
> > return str(self) < str(other)
> >
> > pairs = ((Eq("a"), Eq("b")), (Lt("a"), Lt("b")), (LtEq("a"), LtEq("b")))
> > for a, b in pairs:
> > print("comparing", type(a))
> > try:
> > print("a < b", a < b)
> > except TypeError as err: # TypeError, err in Python 2
> > print(err)
> > # etc, for all the other comparisons
> >
> > For Python 2 I get this output:
> >
> > comparing <type 'instance'> # Eq
> > a < b True
> > a <= b True
> > a == b False
> > a != b True
> > a > b False
> > a >= b False
> >
> > comparing <type 'instance'> # Lt
> > a < b True
> > a <= b True
> > a == b False
> > a != b True
> > a > b False
> > a >= b False
> >
> > comparing <type 'instance'> #LtEq
> > a < b True
> > a <= b True
> > a == b False
> > a != b True
> > a > b False
> > a >= b False
> >
> > Clearly this is bad since class Eq has no ordering and class Lt has no
> > notion of equality.
> >
> > For Python 3 I get this output:
> >
> > comparing <class '__main__.Eq'>
> > unorderable types: Eq() < Eq()
> > unorderable types: Eq() <= Eq()
> > a == b False
> > a != b True
> > unorderable types: Eq() > Eq()
> > unorderable types: Eq() >= Eq()
> >
> > comparing <class '__main__.Lt'>
> > a < b True
> > unorderable types: Lt() <= Lt()
> > a == b False
> > a != b True
> > a > b False
> > unorderable types: Lt() >= Lt()
> >
> > comparing <class '__main__.LtEq'>
> > a < b True
> > unorderable types: LtEq() <= LtEq()
> > a == b False
> > a != b True
> > a > b False
> > unorderable types: LtEq() >= LtEq()
> >
> > This is much better in the case of classes Eq and Lt. But I don't
> > understand why class LtEq does not handle <= or =>. Bear in mind that
> > for class Eq I only defined ==, Python 3 created != for me; similarly
> > for class Lt I defined < and Python created >. Or is my code for LtEq
> > wrong?
> >
> > I know it isn't a problem creating a class decorator or metaclass to
> > "complete" LtEq; I'm just trying to understand how Python 3 comparisons
> > work.
> >
> > Thanks!
--
Mark Summerfield, Qtrac Ltd., www.qtrac.eu
More information about the Python-3000
mailing list