The following piece of code
class point:
def __init__(self, x, y):
self.x = x
self.y = y
def dispc(self):
return ('(' + str(self.x) + ',' + str(self.y) + ')')
def __cmp__(self, other):
return ((self.x > other.x) and (self.y > other.y))
works fine in Python 2, but in Python 3 I get an error:
>>> p=point(2,3)
>>> q=point(3,4)
>>> p>q
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: point() > point()
It only works for ==
and !=
.
You need to provide the rich comparison methods for ordering in Python 3, which are
__lt__
,__gt__
,__le__
,__ge__
,__eq__
, and__ne__
. See also: PEP 207 -- Rich Comparisons.__cmp__
is no longer used.More specifically,
__lt__
takesself
andother
as arguments, and needs to return whetherself
is less thanother
. For example:(This isn't a sensible comparison implementation, but it's hard to tell what you were going for.)
So if you have the following situation:
This will be equivalent to:
which would return
True
.__eq__
would returnTrue
if the points are equal andFalse
otherwise. The other methods work analogously.If you use the
functools.total_ordering
decorator, you only need to implement e.g. the__lt__
and__eq__
methods:This was a major and deliberate change in Python 3. See here for more details.
In Python3 the six rich comparison operators
must be provided individually. This can be abbreviated by using
functools.total_ordering
.This however turns out rather unreadable and unpractical most of the time. Still you have to put similar code pieces in 2 funcs - or use a further helper func.
So mostly I prefer to use the mixin class
PY3__cmp__
shown below. This reestablishes the single__cmp__
method framework, which was and is quite clear and practical in most cases. One can still override selected rich comparisons.Your example would just become:
The PY3__cmp__ mixin class: