wtfpython
wtfpython copied to clipboard
Interned/cached integer in a function
Code example:
>>> def a(b=3000):
... return b is 3000
[...]
>>> a()
True
>>> a(b=3000)
False
From this article: https://utcc.utoronto.ca/~cks/space/blog/python/PythonIsWithLiteral
Thanks @frenzymadness
Both the examples you shared (this one and #257) are very interesting. I'll add them in the next revision (unless someone else wants to raise a PR :)
You can do it more easily:
a = 1111
assert a + 1 == 1112 # True
assert a + 1 is 1112 # False
The key point here is to take a large enough number that it won't be cached by Python.
a = 1
asert a + 1 == 2 # True
assert a + 1 is 1 # True
@david-shiko I'm not sure I understand your point. What you described is already here and the interned numbers are from -5 to 256 for CPython.
My example here is about the default value for kw argument. It shows that even a number much higher than 256 mentioned above can be cached in some cases.
It seems that the Python interpreter uses cached numeric literals on a per-compile basis.
>>> def a(b=3000):
... c = 3000
... print(id(b), id(c), b is c)
...
>>> a()
140032012726032 140032012726032 True
>>> a(3000)
140032012726192 140032012726032 False
>>> b = 3000
>>> c = 3000
>>> print(id(b), id(c), b is c)
140032012726192 140032012726160 False
If you make it into a script file and run it, the whole thing will compile and everything will be True.
def a(b=3000):
c = 3000
print(id(b), id(c), b is c)
a()
a(3000)
b = 3000
c = 3000
print(id(b), id(c), b is c)
139979290826992 139979290826992 True
139979290826992 139979290826992 True
139979290826992 139979290826992 True