4 ms·
the behavior of is seems pretty hard to predict >>> 3.1 is 3.1 True >>> a = 3.1 >>> a is 3.1 False
by fela 11y ago
the behavior of is seems pretty hard to predict
>>> 3.1 is 3.1
True
>>> a = 3.1
>>> a is 3.1
False
- fela 11y agoIt seems to be a case of leaky abstraction, where the way python caches small objects becomes visible, another example: >>> a = 'hn' >>> a is 'hn' True >>> a = ''.join(['h', 'n']) >>> a is 'hn' False >>> a 'hn' >>> a = 'h' + 'n' >>> a is 'hn' True Edit: found another interesting case >>> a = 1 >>> b = 1 >>> a is b True >>> a = 500 >>> b = 500 >>> a is b False
- odonnellryan 11y agoSecond case is because of the range of integers that are cached, right?
- Veedrac 11y agoIt's actually more complicated than that. CPython will cache constants within a scope, so a = 500 b = 500 a is b will give `True`. But the REPL forces each line to compile separately and CPython won't cache across them. However, there's a global cache for integers less than 256 so in that case they're `is`-equivalent even in the REPL.
- Veedrac 11y ago`is` means "do these things reside in the same location in memory?", and the runtime is merely required to give a plausible answer. For inequivalent values or `True`, `False` and `None`, the result is defined. Identity is also preserved across assignment. For everything else, the answer is "whatever the runtime feels like". PyPy, for instance, will always say True for integers and floats. It's not just hard to predict - it's inherently unpredictable. The runtime gets free reign as long as you can't prove that it's lying.