为什么比较python元组的对象是__eq__然后__cmp__调用? [英] Why in comparing python tuples of objects is __eq__ and then __cmp__ called?

查看:199
本文介绍了为什么比较python元组的对象是__eq__然后__cmp__调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当比较对象的元组时,显然调用对象的 __ eq __ 方法,然后调用compare方法:

When comparing tuples of objects apparently the __eq__ method of the object is called and then the compare method:

import timeit

setup = """
import random
import string
import operator

random.seed('slartibartfast')
d={}

class A(object):
    eq_calls = 0
    cmp_calls = 0
    def __init__(self):
        self.s = ''.join(random.choice(string.ascii_uppercase) for _ in
              range(16))
    def __hash__(self): return hash(self.s)
    def __eq__(self, other):
        self.__class__.eq_calls += 1
        return self.s == other.s
    def __ne__(self, other): return self.s != other.s
    def __cmp__(self, other):
        self.__class__.cmp_calls += 1
        return cmp(self.s ,other.s)

for i in range(1000): d[A()] = 0"""
print min(timeit.Timer("""
for k,v in sorted(d.iteritems()): pass
print A.eq_calls
print A.cmp_calls""", setup=setup).repeat(1, 1))

print min(timeit.Timer("""
for k,v in sorted(d.iteritems(),key=operator.itemgetter(0)): pass
print A.eq_calls
print A.cmp_calls""", setup=setup).repeat(1, 1))

打印:

8605
8605
0.0172435735131
0
8605
0.0103719966418

因此,在第二种情况下,我们直接比较键(即A实例) code> __ eq __ 不被调用,而在第一种情况下,显然元组的第一个元素通过等于然后通过cmp进行比较。但为什么他们不直接通过cmp进行比较?我真的不是得到的默认 sorted 行为上没有cmp或键参数。

So in the second case where we compare the keys (that is the A instances) directly __eq__ is not called, while in the first case apparently the first ellement of the tuple are compared via equal and then via cmp. But why are they not compared directly via cmp ? What I really don't quite get is the default sorted behavior on the absence of a cmp or key parameter.

推荐答案

这是如何实现元组比较: tuplerichcompare

It is just how tuple comparison is implemented: tuplerichcompare

它搜索项目不同的第一个索引然后进行比较。这就是为什么你看到 __ eq __ ,然后是 __ cmp __ 调用。
此外,如果您不为A实现 __ eq __ 运算符,您将看到 __ cmp __ 被调用两次一次用于平等和一次用于比较。

it searches the first index where items are different and then compare on that. That's why you see an __eq__ and then a __cmp__ call. Moreover if you do not implement the __eq__ operator for A, you will see that __cmp__ is called twice once for equality and once for comparison.

例如,

print min(timeit.Timer("""
l =list()
for i in range(5): 
    l.append((A(),A(),A()))
    l[-1][0].s='foo'
    l[-1][1].s='foo2'
for _ in sorted(l): pass 
print A.eq_calls
print A.cmp_calls""", setup=setup).repeat(1, 1))

分别打印出24个和8个调用(确切的数字明显取决于随机种子,但在这种情况下,它们的比率总是为3)

prints out 24 and 8 calls respectively (the exact number clearly depends on random seed but in this case they will always have a ratio of 3)

这篇关于为什么比较python元组的对象是__eq__然后__cmp__调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆