Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

the behavior of is seems pretty hard to predict

  >>> 3.1 is 3.1
  True
  >>> a = 3.1
  >>> a is 3.1
  False


It 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


Second case is because of the range of integers that are cached, right?


It'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.


`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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: