问题描述:

When I use the code in Python 2 it works fine while Python 3 it gives me the error

 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))

....................................................................

[email protected]:~/Documents/Programs$ python3 -i classes.py

>>> 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()

>>>

[email protected]:~/Documents/Programs$ python -i classes.py

>>> p=point(2,3)

>>> q=point(3,4)

>>> p>q

False

>>>

...................................................................

In python 3 it gives an error on and while works for only == and !=.

Please suggest a solution.

网友答案:

You need to provide __lt__ and __eq__ method for ordering in Python 3. __cmp__ is no longer used.

Updated to respond to questions/comments below

__lt__ takes self and other as arguments, and needs to return whether self is less than other. For example:

class Point(object):
    ...
    def __lt__(self, other):
        return ((self.x < other.x) and (self.y < other.y))

So if you have the following situation:

p1 = Point(1, 2)
p2 = Point(3, 4)

p1 < p2

This will be equivalent to:

p1.__lt__(p2)

Which would return True. __eq__ would return True if the points are equal and False otherwise. If you use the functools.total_ordering decorator as recommended below, you only need to provide __lt__ and __eq__:

from functools import total_ordering

@total_ordering
class Point(object):
    def __lt__(self, other):
        ...

    def __eq__(self, other):
        ...
网友答案:

This was a major and deliberate change in Python 3. See here for more details.

网友答案:

In Python3 the six rich comparison operators

__lt__(self, other) 
__le__(self, other) 
__eq__(self, other) 
__ne__(self, other) 
__gt__(self, other) 
__ge__(self, other) 

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:

 class point(PY3__cmp__):
      ... 
      # unchanged code

The PY3__cmp__ mixin class:

PY3 = sys.version_info[0] >= 3
if PY3:
    def cmp(a, b):
        return (a > b) - (a < b)
    # mixin class for Python3 supporting __cmp__
    class PY3__cmp__:   
        def __eq__(self, other):
            return self.__cmp__(other) == 0
        def __ne__(self, other):
            return self.__cmp__(other) != 0
        def __gt__(self, other):
            return self.__cmp__(other) > 0
        def __lt__(self, other):
            return self.__cmp__(other) < 0
        def __ge__(self, other):
            return self.__cmp__(other) >= 0
        def __le__(self, other):
            return self.__cmp__(other) <= 0
else:
    class PY3__cmp__:
        pass
网友答案:

Define the correct methods.

相关阅读:
Top