Python中与Java的compareTo()函数相当的函数。
Python中与Java的compareTo()函数相当的函数。
我正在使用Python(3.2)进行一个项目,需要比较用户定义的对象。我习惯了Java中的面向对象编程,其中在指定类的自然排序时,会在类中定义一个compareTo()
方法,如下面的示例所示:\n
public class Foo { int a, b; public Foo(int aa, int bb) { a = aa; b = bb; } public int compareTo(Foo that) { // 如果 this < that,返回一个负数 // 如果 this == that,返回0 // 如果 this > that,返回一个正数 if (this.a == that.a) return this.b - that.b; else return this.a - that.a; } }
\n我对Python中的类/对象相对较新,所以我想知道定义类的自然排序的\"pythonic\"方式是什么?
在Python中,我们可以使用__cmp__()
方法来实现类似于Java中compareTo()
方法的功能。然而,在Python 3中,__cmp__()
方法被废弃,不再被支持。根据Python 3的文档,建议使用其他方法来实现相同的功能。
Python 3的文档中提到,可以使用__lt__()
方法来进行排序,使用__eq__()
方法与__hash__()
方法配合进行等值比较,使用其他相应的特殊方法来实现丰富的比较功能。如果真的需要cmp()
功能,可以使用表达式(a > b) - (a < b)
来代替cmp(a, b)
。
因此,要实现类似的功能,可以先实现__gt__()
和__lt__()
方法,然后使用下面的代码来定义compareTo()
方法:
def compareTo(self, that): return ((self > that) - (self < that))
或者定义compare()
方法:
def compare(cls, a, b): return ((a > b) - (a < b))
然后可以按照下面的方式使用这些方法:
f1 = Foo(1,1) f2 = Foo(2,2) f1.compareTo(f2) Foo.compare(f1,f2)
这样就可以获得相同的功能。
由于Python 3不再支持__cmp__()
方法,我们需要使用其他方法来实现类似于Java中compareTo()
方法的功能。可以通过实现__lt__()
和__gt__()
方法,并使用表达式(a > b) - (a < b)
来代替cmp()
方法来实现相同的功能。
Python中的__lt__、__gt__等特殊方法可以用来为自定义类型实现默认的操作符。可以在语言参考中了解更多相关信息。例如:通过实现__lt__方法来实现自定义类型的比较操作。
class Foo: def __init__ (self, a, b): self.a = a self.b = b def __lt__ (self, other): if self.a == other.a: return self.b < other.b return self.a < other.b def __gt__ (self, other): return other.__lt__(self) def __eq__ (self, other): return self.a == other.b and self.b == other.b def __ne__ (self, other): return not self.__eq__(other)
或者,可以使用functools库中的total_ordering装饰器来简化代码:
from functools import total_ordering @total_ordering class Foo: def __init__ (self, a, b): self.a = a self.b = b def __lt__ (self, other): if self.a == other.a: return self.b < other.b return self.a < other.b def __eq__ (self, other): return self.a == other.b and self.b == other.b
还可以只定义__lt__和__eq__方法,并使用functools库中的total_ordering装饰器。
在Python 2中,如果没有提供__gt__方法,它会自动设置为not __lt__(进行了测试)。但奇怪的是文档中说的不是这样。也许有人可以在Python 3上进行测试?
你是对的,但文档可能只是指反过来,即not (a < b) == (a >= b)(如果未定义后者,会引发异常),所以我猜它会交换参数(如果可能的话)。
我猜文档只是在说,如果__gt__是False,并不意味着__lt__是True。它们可以以一种同时为True/False的方式定义。