为什么可以';我在Python3中使用的方法与Python2中一样?
下面的代码为什么可以';我在Python3中使用的方法与Python2中一样?,python,python-3.x,python-2.x,partial-ordering,Python,Python 3.x,Python 2.x,Partial Ordering,下面的代码 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
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))
在Python2中工作正常,但在Python3中我得到一个错误:
>>> 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()
p=点(2,3)
>>>q=点(3,4)
>>>p>q
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:无序类型:point()>point()
它只适用于
==
和=代码>这是Python3中一个重大的、经过深思熟虑的更改。有关更多详细信息,请参阅
- 当操作数没有有意义的自然排序时,排序比较运算符(
)会引发TypeError
异常。因此,像1<'
,0>无
或lenb)-(a
这样的表达式作为cmp(a,b)
的等价物
您需要在Python3中提供丰富的排序比较方法,即、、和。另见:
\uu\cmp\uu
不再使用
更具体地说,将self
和other
作为参数,并需要返回self
是否小于other
。例如:
class Point(object):
...
def __lt__(self, other):
return ((self.x < other.x) and (self.y < other.y))
将返回True
\uuuu eq\uuu
如果点相等,则返回True
,否则返回False
。其他方法的工作原理类似
如果使用decorator,则只需实现例如\uuult\uuuuuu
和\uuuuuu eq\uuuu
方法:
from functools import total_ordering
@total_ordering
class Point(object):
def __lt__(self, other):
...
def __eq__(self, other):
...
在Python3中,六个丰富的比较运算符
__lt__(self, other)
__le__(self, other)
__eq__(self, other)
__ne__(self, other)
__gt__(self, other)
__ge__(self, other)
必须单独提供。这可以通过使用functools.total\u ordering
进行缩写
然而,事实证明,这在大多数情况下是不可读和不现实的。仍然需要在2个func中放入类似的代码段,或者使用另一个助手func
因此,我更喜欢使用下面所示的mixin类。这重新建立了单一的\uuuu cmp\uuu
方法框架,该框架在大多数情况下都非常清晰和实用。仍然可以覆盖选定的富比较
你的例子就是:
class point(PY3__cmp__):
...
# unchanged code
PY3__cmp__;mixin类:
PY3=sys.version\u info[0]>=3
如果PY3:
def cmp(a、b):
返回(a>b)-(a0
定义(自身、其他):
返回自我。cmp(其他)<0
定义(自身、其他):
返回self.\uuu cmp\uuuu(其他)>=0
定义(自我、其他):
返回self.\uuuu cmp\uuuu(其他)现在您需要定义\uuu hash\uuuu
以在集合中使用您的对象或将其用作dict键。感谢您提供有关使用functools的提示。总排序
!我刚刚在Python3.6上试用了它,我只需要定义\uult\uuuu(self,other)
方法。(可能是因为如果a
和b
都为假,那么a==b
必须为真。)它实际上“必须定义至少一个排序操作:<>=”-通过错误消息我喜欢你编写运算符的方式。但是,请解释这一说法(a>b)-(abool
只是int
的一个子类,因此True
和False
基本上分别是1和0。由于cmp
如果第一个参数小于第二个参数,则返回负值;如果参数相等,则返回零;否则返回正值,因此可以看到False-False==0
,True-False==1
,和False-True==-1
为cmp
提供正确的返回值。在Python 2中,\uuu cmp\uuu
已经被破坏了。
__lt__(self, other)
__le__(self, other)
__eq__(self, other)
__ne__(self, other)
__gt__(self, other)
__ge__(self, other)
class point(PY3__cmp__):
...
# unchanged code
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