Python 3 == 运算符

Python 3 == operator

我对 == 运算符在 Python 中的工作方式感到困惑 3. 从 docs 来看,eq(a, b) 等同于 a == b。另外 eq__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.

您混淆了 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

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

当你这样做时:

"hello" == potato

Python 先调用 "hello".__eq__(potato)。 return NotImplemented,所以 Python 换一种方式尝试:potato.__eq__("hello").

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

Note When a binary (or in-place) method returns NotImplemented the interpreter will try the reflected operation on the other type (or some other fallback, depending on the operator). If all attempts return NotImplemented, the interpreter will raise an appropriate exception. Incorrectly returning NotImplemented will result in a misleading error message or the NotImplemented value being returned to Python code. See Implementing the arithmetic operations for examples.

I'm confused as to how the == operator works in Python 3. From the docs, eq(a, b) is equivalent to a == b. Also eq and __eq__ are equivalent.

不,只有 operator 模块 是这种情况。例如,运算符模块用于将 == 作为函数 传递。但是 operator 与香草 Python 本身没有太大关系。

AFAIK, the docs only talk about the == -> eq mapping, but don't say anything about what happens either one of the arguments is not an object (e.g. 1 == p), or when the first object's.

在Python中一切都是一个对象:一个int是一个对象,一个"class"是一个对象”,一个None 是一个对象,等等。例如,我们可以得到 0__eq__:

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

所以等式是在“intclass”中实现的。正如在 documentation on the datamodel __eq__ 中指定的那样,可以 return 几个值:TrueFalse 但任何其他对象(truthiness 将被计算)。另一方面,如果 NotImplemented 被 returned,Python 将回退并调用等式另一边对象上的 __eq__ 对象。