Python:为什么int类没有像`__lt __()`这样的丰富比较运算符? [英] Python: Why does the int class not have rich comparison operators like `__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屋!