cmp_to_key方法返回一个充当代理键的特殊对象:
class K(object):
__slots__ = ['obj']
def __init__(self, obj, *args):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) < 0
def __gt__(self, other):
return mycmp(self.obj, other.obj) > 0
def __eq__(self, other):
return mycmp(self.obj, other.obj) == 0
def __le__(self, other):
return mycmp(self.obj, other.obj) <= 0
def __ge__(self, other):
return mycmp(self.obj, other.obj) >= 0
def __ne__(self, other):
return mycmp(self.obj, other.obj) != 0
def __hash__(self):
raise TypeError('hash not implemented')
排序时,每个键将与序列中的大多数其他键进行比较。这个元素在位置0是否低于或大于其他对象?
只要发生这种情况,就会调用特殊的方法钩子,因此调用__lt__或__gt__,代理键变成对cmp方法的调用。
因此,列表[1,2,3]被排序为[K(1),K(2),K(3)],并且如果比较K(1) (1)的值较低,则调用K(1).__ lt__(K(2)),将其转换为mycmp(1,2) 0。
这是老cmp方法是如何工作;返回-1,0或1,取决于第一个参数是否小于,等于或大于第二个参数。代理键将这些数字转换回比较运算符的布尔值。
代理键在任何时候都不需要知道绝对位置的任何东西。它只需要知道正在比较的另一个对象,特殊方法钩子提供了另一个对象。