首页 > 解决方案 > 将类与无进行比较

问题描述

我有一个简单的情况,我正在尝试对包含混合类实例和无的列表进行排序。我已经实现了该类的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])

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

提前致谢!

标签: python

解决方案


请注意,您的错误不是

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__知道如何与 a 进行比较的方法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__都已定义一样,即使您只需要定义一个。


推荐阅读