Why can't I use the method __cmp__ in Python 3 as for Python 2?
下面这段代码
1 2 3 4 5 6 7 8 9 10 | 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)) |
在python 2中工作正常,但在python 3中,我得到一个错误:
1 2 3 4 5 6 | >>> 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() |
号
它只适用于
在python 3中需要提供丰富的排序比较方法,分别是
不再使用
更具体地说,
1 2 3 4 | class Point(object): ... def __lt__(self, other): return ((self.x < other.x) and (self.y < other.y)) |
(这不是一个明智的比较实现,但是很难知道您要做什么。)
因此,如果您有以下情况:
1 2 3 4 | p1 = Point(1, 2) p2 = Point(3, 4) p1 < p2 |
号
这相当于:
1 | p1.__lt__(p2) |
将返回
如果积分相等,
如果使用
1 2 3 4 5 6 7 8 9 | from functools import total_ordering @total_ordering class Point(object): def __lt__(self, other): ... def __eq__(self, other): ... |
。
这是python 3中一个重大的、经过深思熟虑的变化。有关详细信息,请参阅此处。
- The ordering comparison operators (
< ,<= ,>= ,> ) raise aTypeError exception when the operands don’t have a meaningful natural ordering. Thus, expressions like1 < '' ,0 > None orlen <= len are no longer valid, and e.g.None < None raisesTypeError instead of returningFalse . A corollary is that sorting a heterogeneous list no longer makes sense – all the elements must be comparable to each other. Note that this does not apply to the== and!= operators: objects of different incomparable types always compare unequal to each other.builtin.sorted() andlist.sort() no longer accept thecmp argument providing a comparison function. Use thekey argument instead. N.B. thekey andreverse arguments are now"keyword-only".- The
cmp() function should be treated as gone, and the__cmp__() special method is no longer supported. Use__lt__() for sorting,__eq__() with__hash__() , and other rich comparisons as needed. (If you really need thecmp() functionality, you could use the expression(a > b) - (a < b) as the equivalent forcmp(a, b) .)
号
在python3中,六个丰富的比较运算符
1 2 3 4 5 6 | __lt__(self, other) __le__(self, other) __eq__(self, other) __ne__(self, other) __gt__(self, other) __ge__(self, other) |
必须单独提供。这可以通过使用
然而,大多数情况下,这是不可读和不实际的。不过,您仍然需要在2个函数中放入类似的代码片段——或者使用另一个helper func。
所以我更喜欢使用下面显示的mixin类
您的示例将变成:
1 2 3 | class point(PY3__cmp__): ... # unchanged code |
。Py3_uuu cmp_uuuuuu混音类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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 |
。