我注意到operator.itemgetter
个对象没有定义__eq__
,因此他们的比较默认为检查身份(is
)。
当初始化参数列表比较为相等时,将两个itemgetter
实例定义为相等是否有任何缺点?
这是这种比较的一个用例。假设您定义了一个排序数据结构,其构造函数需要一个键函数来定义排序。假设您要检查两个这样的数据结构是否具有相同的键功能(例如,在assert
语句中;或者验证它们是否可以安全地合并;等等。)
如果我们能够在两个关键函数为itemgetter('id')
时回答肯定的问题,那就太好了。但目前,itemgetter('id') == itemgetter('id')
会评估为False
。
答案 0 :(得分:4)
尼克拉斯的答案非常聪明,但需要更强的条件,因为itemgetter
可以采取多个论点
from collections import defaultdict
from operator import itemgetter
from itertools import count
def cmp_getters(ig1, ig2):
if any(not isinstance(x, itemgetter) for x in (ig1, ig2)):
return False
d1 = defaultdict(count().next)
d2 = defaultdict(count().next)
ig1(d1) # populate d1 as a sideeffect
ig2(d2) # populate d2 as a sideeffect
return d1==d2
一些测试用例
>>> cmp_getters(itemgetter('foo'), itemgetter('bar'))
False
>>> cmp_getters(itemgetter('foo'), itemgetter('bar','foo'))
False
>>> cmp_getters(itemgetter('foo','bar'), itemgetter('bar','foo'))
False
>>> cmp_getters(itemgetter('bar','foo'), itemgetter('bar','foo'))
True
答案 1 :(得分:0)
itemgetter
返回一个可调用的。我希望你不想比较callables 。正确?因为即使传递相同的参数,返回的callable的id也不会保持相同。
def fun(a):
def bar(b):
return a*b
return bar
a = fun(10)
print id(a(10))
a = fun(10)
print id(a(10))
另一方面,当您使用itemgetter callable作为访问者来访问底层对象时,该对象的比较将用于执行比较 它在Sorting Howto using the operating module functions中有说明。