5

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

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
4

2 回答 2

3

我个人的做法:

一个例外。

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

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

虽然我不完全同意这一点,但手册清楚地说明了应该如何做:

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

不同类型的对象,除了不同的数值类型和不同的字符串类型,从不比较相等;此类对象的排序一致但任意(因此对异构数组进行排序会产生一致的结果)。此外,某些类型(例如,文件对象)仅支持退化的比较概念,其中该类型的任何两个对象都不相等。同样,这些对象的顺序是任意但一致的。当任何操作数是复数时,<、<=、> 和 >= 运算符将引发 TypeError 异常。

所以基本上......我会提出一个例外,但最pythonic的排序方式是遵守手册。

应该有一种——最好只有一种——明显的方法来做到这一点。

于 2012-08-07T12:06:06.640 回答
3

你可以选择任何你觉得自然的东西;False意味着您的实例总是在其他类型之后排序,True并且它们将在之前排序。

或者,您可以返回NotImplemented(参见__lt__其他比较方法文档)以表示不支持比较:

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

引用文档:

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

于 2012-08-07T12:06:37.320 回答