将类与“无”进行比较

时间:2019-07-19 02:54:02

标签: python

我的情况很简单,我试图对包含类实例和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])

...会产生上述错误。谁能指出我做错了什么?在某种理想化的现实中,编程语言以常识的方式工作,我本以为“如果其他都不是”位应该处理与“无”的比较。

谢谢!

1 个答案:

答案 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__都被定义了,即使您只需要定义一个。