我很困惑==
运算符如何在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 == b
或operator.__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__
的方法查找。
当你这样做:
"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代码。有关示例,请参阅实现算术运算。
我很困惑= =运算符如何在Python 3中工作。从文档中,
eq(a, b)
相当于a == b
。eq
和__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__
可以返回几个值:True
,False
但是任何其他对象(为此将计算真实性)。另一方面,如果返回NotImplemented
,Python将回退并调用等式另一侧的对象上的__eq__
对象。