下面这段代码
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中我得到一个错误:
>>> 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()
它只适用于==
和!=
。
4条答案
按热度按时间6za6bjd01#
你需要提供丰富的比较方法来在Python 3中排序,它们是
__lt__
、__gt__
、__le__
、__ge__
、__eq__
和__ne__
。另请参阅:PEP 207 -- Rich Comparisons。__cmp__
不再使用。具体来说,
__lt__
以self
和other
为参数,需要返回self
是否小于other
。例如:(This不是一个明智的比较实现,但很难判断您想要的是什么。)
所以如果你有以下情况:
这相当于:
这将返回
True
。__eq__
如果两个点相等,则返回True
,否则返回False
。其他方法的工作原理类似。如果你使用
functools.total_ordering
装饰器,你只需要实现例如__lt__
和__eq__
方法:oknrviil2#
这是Python 3中的一个重大而深思熟虑的变化。更多细节请参见此处。
<
,<=
,>=
,>
)在操作数没有有意义的自然顺序时引发TypeError
异常。因此,像1 < ''
,0 > None
或len <= len
这样的表达式不再有效,例如,None < None
引发TypeError
而不是返回False
。一个推论是,对异构列表进行排序不再有意义-所有元素必须彼此可比较。请注意,这不适用于==
和!=
运算符:不同的不可比类型的对象总是彼此比较不相等。builtin.sorted()
和list.sort()
不再接受提供比较函数的cmp
参数。使用key
参数代替。注意:key
和reverse
参数现在是“仅关键字”。cmp()
函数应该被视为已经消失,并且不再支持__cmp__()
特殊方法。使用__lt__()
进行排序,__eq__()
与__hash__()
以及其他需要的丰富比较。(如果您确实需要cmp()
功能,您可以使用表达式(a > b) - (a < b)
作为cmp(a, b)
的等效表达式。)bxfogqkk3#
在Python 3中,六个丰富的比较运算符
必须单独提供。可以缩写为
functools.total_ordering
。然而,这在大多数情况下是不可读和不切实际的。你仍然必须把类似的代码片段放在2个函数中-或者使用另一个帮助函数。
因此,我更喜欢使用下面的mixin类
PY3__cmp__
。这重新建立了单一的__cmp__
方法框架,在大多数情况下,这是非常清晰和实用的。仍然可以覆盖选定的丰富比较。你的例子会变成:
PY3__cmp__混合类:
wfveoks04#
Python 2是超前的,因为
__cmp__
运算符实现three-way comparison目前在C++(宇宙飞船运算符)和其他地方越来越流行。参见Universal Comparison Operator In Python?。原则上,我喜欢KXR的mixin类,但对我来说,装饰器更合适
PY3__cmp__
装饰器是根据@krx的答案和functools.total_ordering
装饰器建模的。(And是的,我的代码库仍然保留了PEP-8之前关于缩进的一些想法。)