Python 3 ==运算符

问题描述 投票:2回答:3

我很困惑==运算符如何在Python 3中工作。从docseq(a, b)相当于a == beq__eq__也是等价的。

请看以下示例:

class Potato:
    def __eq__(self, other):
        print("In Potato's __eq__")
        return True

>> p = Potato()
>> p == "hello"
In Potato's __eq__ # As expected, p.__eq__("hello") is called
True
>> "hello" == p
In Potato's __eq__ # Hmm, I expected this to be false because
True               # this should call "hello".__eq__(p)
>> "hello".__eq__(p)
NotImplemented     # Not implemented? How does == work for strings then?

AFAIK,文档只讨论== - > __eq__映射,但不要说任何事情发生的任何一个参数不是一个对象(例如1 == p),或者当第一个对象的__eq__NotImplemented时,就像我们看到的那样"hello".__eq(p)

我正在寻找用于平等的通用算法...大多数,如果不是所有其他SO答案,请参考Python 2的coercion rules,它不再适用于Python 3。

python python-3.x equality
3个回答
6
投票

您正在混合operator模块中的函数以及用于实现这些运算符的方法。 operator.eq(a, b)相当于a == boperator.__eq__(a, b),但不是a.__eq__(b)

__eq__方法而言,==operator.eq的工作原理如下:

def eq(a, b):
    if type(a) is not type(b) and issubclass(type(b), type(a)):
        # Give type(b) priority
        a, b = b, a

    result = a.__eq__(b)
    if result is NotImplemented:
        result = b.__eq__(a)
    if result is NotImplemented:
        result = a is b
    return result

需要注意的是,真实代码以绕过实例dicts和自定义__eq__ / __getattribute__方法的方式执行__getattr__的方法查找。


3
投票

当你这样做:

"hello" == potato

Python首先调用"hello".__eq__(potato)。返回NotImplemented,所以Python以另一种方式尝试:potato.__eq__("hello")

返回NotImplemented并不意味着没有在该对象上实施.__eq__。这意味着实现不知道如何与传入的值进行比较。来自https://docs.python.org/3/library/constants.html#NotImplemented

注意当二进制(或就地)方法返回NotImplemented时,解释器将尝试对另一种类型(或其他一些后备,取决于运算符)的反射操作。如果所有尝试都返回NotImplemented,则解释器将引发适当的异常。错误地返回NotImplemented将导致误导性错误消息或NotImplemented值返回到Python代码。有关示例,请参阅实现算术运算。


1
投票

我很困惑= =运算符如何在Python 3中工作。从文档中,eq(a, b)相当于a == beq__eq__也是等价的。

不,这只是operator模块中的情况。运算符模块用于传递==作为函数。但是operator与香草Python本身没什么关系。

AFAIK,文档只讨论== - > eq映射,但是没有说明发生的事情,其中​​一个参数不是一个对象(例如1 == p),或者第一个对象的时候。

在Python中,一切都是对象:int是一个对象,“class”是一个对象“,None是一个对象,等等。我们可以得到__eq__0

>>> (0).__eq__
<method-wrapper '__eq__' of int object at 0x55a81fd3a480>

因此,平等在“int类”中实现。正如在documentation on the datamodel中指定的那样,__eq__可以返回几个值:TrueFalse但是任何其他对象(为此将计算真实性)。另一方面,如果返回NotImplemented,Python将回退并调用等式另一侧的对象上的__eq__对象。

© www.soinside.com 2019 - 2024. All rights reserved.