0

I came across this phrase:

"Python keeps an array of ints between -5 and 256. When you create an int in that range, you get a reference to a pre-existing object"

You can verify with this code:

def check(n,d):  
    a = b = n     
    a -= d
    b -= d 
    return a is b

Now, check(500,10) returns False. But check(500,300) returns True. Why does Python compiler would do such a thing? Isn't it a perfect recipe for bugs?

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
aartist
  • 3,145
  • 3
  • 33
  • 31
  • 5
    No it's not a "perfect recipe" because you should *never* be using `is` to compare integers. – Mark Ransom Jun 08 '20 at 19:48
  • 3
    what kind of bugs are you foreseeing? ints are immutable anyways... – Tomerikoo Jun 08 '20 at 19:48
  • 1
    Integers are immutable – Pynchia Jun 08 '20 at 19:49
  • It is not a recipe for bug, but it is a good question I think. Python choses when to reassign an int internally to point to a different memory address/value. Altho your a/b values are always the same, their `id()` might not be! So I would recommend you adding `print(id(a), id(b))` to see what is happening and do not use `is`for comparison (https://stackoverflow.com/questions/13650293/understanding-pythons-is-operator) – urban Jun 08 '20 at 19:54
  • Related: https://stackoverflow.com/questions/15171695/whats-with-the-integer-cache-maintained-by-the-interpreter – Tomerikoo Jun 08 '20 at 20:01
  • 5
    The "bug" only occurs when erroneously using the *identity* operator instead of the *equality* operator. Using ``is`` instead of ``==`` is the bug already, not the implementation defined result. – MisterMiyagi Jun 08 '20 at 20:02

1 Answers1

3

CPython (the reference interpreter) does it because it saves a lot of memory (and a small amount of execution time) to have the most commonly used ints served from a cache. Incrementing a number uses a shared temporary, not a unique value in each place you do the increment. Iterating a bytes or bytearray object can go much faster by directly pulling the cached entries. It's not a language guarantee though, so never write code like this (which relies on it).

It's not a bug factory because:

  1. Relying on object identity tests for ints is a terrible idea in the first place; you should always be using == to compare ints, and
  2. ints are immutable; it's impossible to modify the cached entries without writing intentionally evil ctypes or C extension modules. Normal Python code can't trigger bugs due to this cache.
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271