Quantcast
Channel: Planet Python
Viewing all articles
Browse latest Browse all 22462

Holger Peters: Identical Objects Do Not Imply Equality In Python

$
0
0

Python has two very similar comparison operators: == for equality and is for object identity. Typically, is faster, as the implementation just needs to compare object ids, whereas == must call the __eq__ method, and is therefor slower.

The operator is is recommended for comparisons with None in Python (as in if a is None). And I was asking myself how much overhead the == method would be in this case. So I figured that the None == None case might be more efficient, than the generic a == None case, because the runtime could first check for identity before deciding to call __eq__.

As it happens, Python has strange semantics with respect to these operators, and my assumption was wrong. I was assuming that a == a was always True (since a is a is True, and identity should imply equality). This is, however, not the case:

In[1]:classA:...:def__eq__(self,rhs):...:returnFalse...:In[2]:a=A()In[3]:a==aOut[3]:False

(tested with Python 3.5). [1]

I haven't found much in the Python docs [2] about this, but I guess that someone has a use case where a==a should evaluate to false, although objects are identical. Another explanation would be that if __eq__ would have a side-effect, it should be called in any case, even for identical objects. Right now, I cannot think of any cases where either of these options would be desirable. So if you stumble over classes where a == a does not evaluate to True it might be worth investigating.

Footnotes

[1]

Ruby does not do it any other way. I find it a bit less surprising, here, as we direcly overwrite the == operator that is called later, instead of Python's approach of using a protocol method __eq__:

irb(main):001:0>classAirb(main):002:1>def==(rhs)irb(main):003:2>falseirb(main):004:2>endirb(main):005:1>endirb(main):011:0>a=A.new=>#<A:0x007fda8190f2c8>irb(main):013:0>a==a=>falseirb(main):015:0>a===a=>true
[2]https://docs.python.org/3/reference/datamodel.html?highlight=__eq__#object.__eq__

Viewing all articles
Browse latest Browse all 22462

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>