Python:为什么int类没有像`__lt __()`这样的丰富比较运算符? [英] Python: Why does the int class not have rich comparison operators like `__lt__()`?

查看:89
本文介绍了Python:为什么int类没有像`__lt __()`这样的丰富比较运算符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最好奇.

我注意到(至少在py 2.6和2.7中)float具有所有熟悉的丰富比较功能:__lt__()__gt____eq__等.

I've noticed (at least in py 2.6 and 2.7) that a float has all the familiar rich comparison functions: __lt__(), __gt__, __eq__, etc.

>>> (5.0).__gt__(4.5)
True

int不会

>>> (5).__gt__(4)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'int' object has no attribute '__gt__'

这对我来说很奇怪,因为操作员本身可以很好地工作

Which is odd to me, because the operator itself works fine

>>> 5 > 4
True

甚至字符串都支持比较功能

Even strings support the comparison functions

>>> "hat".__gt__("ace")
True

,但所有int都具有__cmp__()

对我来说似乎很奇怪,所以我想知道为什么会这样.

Seems strange to me, and so I was wondering why this came to be.

经过测试,它可以在python 3中按预期工作,因此我假设有一些遗留原因.虽然还是很想听到一个适当的解释;)

Just tested and it works as expected in python 3, so I am assuming some legacy reasons. Still would like to hear a proper explanation though ;)

推荐答案

如果我们查看

If we look at the PEP 207 for Rich Comparisions there is this interesting sentence right at the end:

处理整数比较的内联仍然适用,因此在大多数情况下不会降低性能.

The inlining already present which deals with integer comparisons would still apply, resulting in no performance cost for the most common cases.

因此,在2.x中似乎有一个用于整数比较的优化.如果我们看看源代码我们可以找到这个:

So it seems that in 2.x there is an optimisation for integer comparison. If we take a look at the source code we can find this:

case COMPARE_OP:
    w = POP();
    v = TOP();
    if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) {
        /* INLINE: cmp(int, int) */
        register long a, b;
        register int res;
        a = PyInt_AS_LONG(v);
        b = PyInt_AS_LONG(w);
        switch (oparg) {
        case PyCmp_LT: res = a <  b; break;
        case PyCmp_LE: res = a <= b; break;
        case PyCmp_EQ: res = a == b; break;
        case PyCmp_NE: res = a != b; break;
        case PyCmp_GT: res = a >  b; break;
        case PyCmp_GE: res = a >= b; break;
        case PyCmp_IS: res = v == w; break;
        case PyCmp_IS_NOT: res = v != w; break;
        default: goto slow_compare;
        }
        x = res ? Py_True : Py_False;
        Py_INCREF(x);
    }
    else {
      slow_compare:
        x = cmp_outcome(oparg, v, w);
    }

因此,似乎在2.x中存在一个现有的性能优化-通过允许C代码直接比较整数-如果实现了丰富的比较运算符,则不会保留该性能.

So it seems that in 2.x there was an existing performance optimisation - by allowing the C code to compare integers directly - which would not have been preserved if the rich comparison operators had been implemented.

现在不再支持Python 3 __cmp__,因此丰富的比较运算符必须在那里.现在,就我所知,这不会造成性能下降.例如,比较:

Now in Python 3 __cmp__ is no longer supported so the rich comparison operators must there. Now this does not cause a performance hit as far as I can tell. For example, compare:

Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>> timeit.timeit("2 < 1")
0.06980299949645996

收件人:

Python 3.2.3 (v3.2.3:3d0686d90f55, Apr 10 2012, 11:25:50) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>> timeit.timeit("2 < 1")
0.06682920455932617

因此,似乎也存在类似的优化,但我的判断是,如果考虑到向后兼容性,将它们全部放入2.x分支将是一个很大的改变.

So it seems that similar optimisations are there but my guess is the judgement call was that putting them all in the 2.x branch would have been too great a change when backwards compatibility was a consideration.

在2.x中,如果您想要类似丰富的比较方法的方法,则可以通过 operator模块:

In 2.x if you want something like the rich comparison methods you can get at them via the operator module:

>>> import operator
>>> operator.gt(2,1)
True

这篇关于Python:为什么int类没有像`__lt __()`这样的丰富比较运算符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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