如何在实现比较运算符时处理混合类型?

时间:2012-08-07 12:04:47

标签: python comparison

完成以下代码的最自然方式是什么?

import functools

@functools.total_ordering
class X:
    def __init__(self, a):
        self._a = a

    def __eq__(self, other):
        if not isinstance(other, X):
            return False
        return self._a == other._a

    def __lt__(self, other):
        if not isinstance(other, X):
            return ...                    // what should go here?
        return self._a < other._a

if __name__ == '__main__':
    s = [2, 'foo', X(2)]
    s.sort()
    print s

2 个答案:

答案 0 :(得分:4)

我的个人方法:

例外。

不同类型之间没有自然顺序。

官方的一个:(选择这一个,应该有)

虽然我完全不同意,但手册中明确说明了应该如何做到:

http://docs.python.org/library/stdtypes.html#comparisons

  

不同类型的对象,不同的数字类型和   不同的字符串类型,从不比较平等;这样的对象是有序的   一致但任意(以便排序异构数组   产生一致的结果)。此外,某些类型(例如,   文件对象)只支持任何比较的简并比较概念   这种类型的两个对象是不相等的。同样,这些对象是有序的   任意但始终如一。 &lt;,&lt; =,&gt;和&gt; =运算符将提升   任何操作数是复数时的TypeError异常。

所以基本上......我会提出异常,但最顺便的做法是遵守手册。

  

应该有一个 - 最好只有一个 - 显而易见的方法。

答案 1 :(得分:2)

你可以选择任何你觉得自然的东西; False表示您的实例始终按其他类型True排序,并且之前会对它们进行排序。

或者,您可以返回NotImplemented(请参阅the __lt__ and other comparison methods documentation)以表示不支持比较:

def __lt__(self, other):
    if not isinstance(other, X):
        return NotImplemented
    return self._a < other._a

引用文档:

  

如果丰富的比较方法没有实现给定参数对的操作,则它可以返回单例NotImplemented。按照惯例,返回FalseTrue以进行成功比较。但是,这些方法可以返回任何值,因此如果在布尔上下文中使用比较运算符(例如,在if语句的条件下),Python将在值上调用bool()以确定结果是否为true或者是假的。