int()对象如何在python2中使用“==”运算符而不使用__eq __()方法?

时间:2016-04-28 17:25:57

标签: python python-2.7 python-internals

最近我阅读了“Fluent python”并了解了==运算符如何使用__eq__()方法处理python对象。但它如何与python2中的int个实例一起使用?

>>> a = 1
>>> b = 1
>>> a == b
True
>>> a.__eq__(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__eq__'

在python3中,所有a.__eq__(b)都会返回True

3 个答案:

答案 0 :(得分:9)

Python prefers to use rich comparison functions__eq____lt____ne__等),但如果不存在,则会回退到使用单个比较功能( {3}中删除的__cmp__

  

这些是所谓的“丰富比较”方法,并且优先于下面的__cmp__()调用比较运算符。

Python 2 integer type未实现丰富的比较功能:

PyTypeObject PyInt_Type = {
    ...
    (cmpfunc)int_compare,                       /* tp_compare */
    ...
    0,                                          /* tp_richcompare */

在Python 3中,integer type(现在很长)只实现了一个丰富的比较函数,因为Python 3放弃了对__cmp__的支持:

PyTypeObject PyLong_Type = {
    ...
    long_richcompare,                           /* tp_richcompare */

这就是(123).__eq__不存在的原因。相反,当测试两个整数的相等性时,Python 2会回退到(123).__cmp__

>>> (1).__eq__(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__eq__'
>>> (1).__cmp__(2)
-1

答案 1 :(得分:6)

在Python 2中,int对象使用__cmp__()方法而不是__eq__()__lt__()__gt__()等其他方法。< / p>

答案 2 :(得分:0)

这是我的答案。

import sys
SPECIAL_OPNAMES = \
    { '__eq__': (lambda *args, **kwargs: not cmp(*args, **kwargs)) \
    , '__ne__': (lambda *args, **kwargs: cmp(*args, **kwargs)) \
    , '__lt__': (lambda *args, **kwargs: cmp(*args, **kwargs) < 0) \
    , '__ge__': (lambda *args, **kwargs: cmp(*args, **kwargs) >= 0) \
    , '__gt__': (lambda *args, **kwargs: cmp(*args, **kwargs) > 0) \
    , '__le__': (lambda *args, **kwargs: cmp(*args, **kwargs) <= 0) \
    } if sys.version_info.major == 2 else \
    {}

工作示例:

>>> item = 1
>>> opname = '__eq__'
>>> t = type(item)
>>> op = SPECIAL_OPNAMES[opname] if opname in SPECIAL_OPNAMES else getattr(t, opname)
>>> op(item, 1)
True