I know that python has a concept of small integers which are numbers from -5 to 256, and if two variables assign to same numbers between this range, they both will use the same underlying object.
From Python documentation,
#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS 257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS 5
#endif
/* Small integers are preallocated in this array so that they can
be shared. The integers that are preallocated are those in the
range -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
The current implementation keeps an array of integer objects for all
integers between -5 and 256, when you create an int in that range you
actually just get back a reference to the existing object. So it
should be possible to change the value of 1. I suspect the behaviour
of Python in this case is undefined. :-)
Example,
a = 255
b = 255
print(id(a))
print(id(b))
gives the same id,
1561854394096
1561854394096
Which makes sense and also explained on this answer, "is" operator behaves unexpectedly with integers
If two numbers are less than -5, they should also have different IDs as follows,
a = -6
b = -6
print(id(a))
print(id(b))
gives,
2827426032208
2827426032272
this makes sense so far,
But any number greater than 256 should have different id,
This should return different IDs,
a = 257
b = 257
print(id(a))
print(id(b))
But it doesn't
2177675280112
2177675280112
Even when I am using very large integer, the IDs are same,
a = 2571299123876321621378
b = 2571299123876321621378
print(id(a))
print(id(b))
gives me,
1956826139184
1956826139184
Can someone tell me why number greater than 256 have same IDs even though in the Python code the range is -5 to 257 (not inclusive)
EDIT:
I have tried using PyCharm with both Python 2.7 and 3.6. Also tried on PythonTutor.com
解决方案
On mint Python 3.6.3 (2 as well) I cannot reproduce. My guess is PyCharm or pythontutor are wrapping the run in something before interpreting - since those are not open code we cannot see the internals so I cannot verify. The reason I think this is true, is while (everything below is mint Python 3):
>>> x=2571299123876321621378
>>> y=2571299123876321621378
>>> print(id(x),id(y))
140671727739528 140671727739808
You can have this:
>>> def bla():
... x=2571299123876321621378
... y=2571299123876321621378
... id(x)
... print(id(x),id(y))
...
>>> bla()
140671727742528 140671727742528
so wrapping the two integers in something the interpreter can compile allows for these extra optimizations - like using the same constant for both definitions. Note this is limited as well:
>>> def bla():
... x=2571299123876321621378
... y=2571299123876321621378
... print(id(x),id(y))
... x+=1
... y+=1
... print(id(x),id(y))
...
>>> bla()
140671727755592 140671727755592
140671728111088 140671728108808
I would not have code that depends on this on any way - the guarantee is only on -5 to 256.