How does Python know the values already stored in its memory?

Jus*_*one 10 python memory python-3.x

I want to know how Python knows (if it knows) that a value-type object is already stored in its memory (and also knows where it is).

For this code, when assigning the value 1 for b, how does it know that the value 1 is already in its memory and stores its reference in b?

>>> a = 1
>>> b = 1
>>> a is b
True
Run Code Online (Sandbox Code Playgroud)

asn*_*184 13

Python (CPython precisely) uses shared small integers to help quick access. Integers range from [-5, 256] already exists in memory, so if you check the address, they are the same. However, for larger integers, it's not true.

a = 100000
b = 100000
a is b # False
Run Code Online (Sandbox Code Playgroud)

Wait, what? If you check the address of the numbers, you'll find something interesting:

a = 1
b = 1
id(a) # 4463034512
id(b) # 4463034512

a = 257
b = 257
id(a) # 4642585200
id(b) # 4642585712
Run Code Online (Sandbox Code Playgroud)

It's called integer cache. You can read more about the integer cache here.

感谢@KlausD和@ user2357112的评论,对小整数的直接访问将使用整数缓存,而如果您进行计算,尽管它们可能等于[-5,256]范围内的数字,则它不是缓存的整数。例如

pow(3, 47159012670, 47159012671) is 1 # False
pow(3, 47159012670, 47159012671) == 1 # True
Run Code Online (Sandbox Code Playgroud)

“当前的实现为-5到256之间的所有整数保留一个整数对象数组,当您在该范围内创建一个int时,实际上只是返回对现有对象的引用。”

为什么?因为小整数更常被循环使用。使用对现有对象的引用而不是创建新对象可以节省开销。

  • 为了清楚起见:这对CPython解释器有效。Python语言未定义此语言,其他解释器可以自由使用自己的实现。 (6认同)
  • 同样,“ 10e5”是浮点数,而不是整数。(此外,并非所有小整数都来自小整数缓存。例如,在当前的CPython上,“ pow(3,47159012670,47159012671)== 1”,但“ pow(3,47159012670,47159012671)不是1”。 ) (2认同)

Mad*_*ist 5

如果看一下Objects/longobject.c实现intCPython类型的,您会看到-5(NSMALLNEGINTS)和256(NSMALLPOSINTS - 1)之间的数字已预先分配和缓存。这样做是为了避免为最常用的整数分配多个不必要的对象的麻烦。这是可行的,因为整数是不可变的:您不需要多个引用来表示相同的数字。