Search code examples
pythonpython-3.xpycharmgoogle-colaboratorypython-idle

Why python integer caches range [-5, 256] don't work in similar way on all platform?


For example:

In pycharm:

a = 256
b = 256
print(a is b)
>>>True  # This is fine.

But!

a = 257
b = 257
print(a is b)
>>>True  # This should be False.

In Colaboratory/IDLE/etc.:

a = 256
b = 256
print(a is b)
>>>True  # This is fine.


a = 257
b = 257
print(a is b)
>>>False  # This is fine.

According to theory:

An integer is referenced in that range, Python will use the cached version of that object. So memory address will be the same.

Expect pycharm this works everywhere.

Can anyone tell me what's the problem.


Solution

  • To simplify what has been mentioned in the comments above and further illustrate it:

    It happens because in your first example the whole block is compiled before being run - which allows the compiler to optimize it before the code itself is invoked, while in the second case each statement is being compiled and run by itself (without knowing anything about the previous statements).

    In the latter case only the small integer cache comes into effect, since the compiler doesn't know anything about the previous statements.

    Do not rely on this in any way. If you save your statements to a file and run that, it'll show the same result as PyCharm:

    ~ cat test.py
    a = 257
    b = 257
    print(a is b)
    ~ python3 test.py
    True
    ~ python test.py
    True 
    

    You can also replicate this behaviour in the REPL by giving it a single block to compile:

    >>> def test():
    ...   a = 257
    ...   b = 257
    ...   print(a is b)
    ...
    >>> test()
    True