我的情况很简单,我试图对包含类实例和None的列表进行排序。我已经实现了该类的 lt 方法,但是仍然出现错误:
TypeError: '<' not supported between instances of 'NoneType' and 'test_class
这是我目前的操作方式:
class test_class:
def __init__(self, num):
self.num = num
def __lt__(self, other):
if other is None:
return False
else:
return self.num < other.num
def __eq__(self, other):
if other is None:
return False
else:
return self.num == other.num
tc1 = test_class(1)
tc2 = test_class(2)
sorted([tc1, tc2, None])
...会产生上述错误。谁能指出我做错了什么?在某种理想化的现实中,编程语言以常识的方式工作,我本以为“如果其他都不是”位应该处理与“无”的比较。
谢谢!
答案 0 :(得分:1)
请注意,您的错误不是
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'test_class' and 'NoneType'
但是
...between instances of 'NoneType' and 'test_class'
订购很重要。 None
没有实现知道如何与__lt__
比较的test_class
方法。但是,在这种情况下,Python足够聪明,可以使用其他类的__gt__
。
class TestClass(object):
def __init__(self, num):
self.num = num
def __lt__(self, other):
if other is None:
return False
else:
return self.num < other.num
def __gt__(self, other):
if other is None:
return True
return self.num > other.num
def __eq__(self, other):
if other is None:
return False
else:
return self.num == other.num
此外,functools.total_ordering
可用于装饰您的类,因此您只需定义__eq__
和__lt__
,__le__
,__gt__
中的一个, __ge__
,其余的将自动为您生成。
import functools
@functools.total_ordering
class TestClass(object):
def __init__(self, num):
self.num = num
def __lt__(self, other):
if other is None: return False
return self.num < other.num
def __eq__(self, other):
return isinstance(other, type(self)) and self.num == other.num
# I refactored this to be a little nicer
现在TestClass()
的行为就好像__gt__
,__ge__
和__le__
都被定义了,即使您只需要定义一个。