Как Python узнает значения, уже хранящиеся в его памяти?

Я хочу знать, как Python знает (если он знает), что объект типа значения уже хранится в его памяти (а также знает, где он находится).

Для этого кода при назначении значения 1 для b как он узнает, что значение 1 уже находится в его памяти, и сохраняет свою ссылку в b?

>>> a = 1
>>> b = 1
>>> a is b
True

Ответы

Ответ 1

Python (точнее, CPython) использует общие маленькие целые числа для быстрого доступа. Целые числа от [-5, 256] уже существуют в памяти, поэтому, если вы проверите адрес, они будут одинаковыми. Однако для больших целых чисел это не так.

a = 100000
b = 100000
a is b # False

Чего ждать? Если вы проверите адрес чисел, вы найдете что-то интересное:

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

a = 257
b = 257
id(a) # 4642585200
id(b) # 4642585712

Это называется целочисленным кешем. Вы можете прочитать больше о целочисленном кеше здесь.

Благодаря комментариям @KlausD и @user2357112, в которых упоминается, прямой доступ к маленьким целым числам будет использовать целочисленный кеш, а если вы выполняете вычисления, хотя они могут равняться числу в диапазоне [-5, 256], это не кэшированное целое число. например

pow(3, 47159012670, 47159012671) is 1 # False
pow(3, 47159012670, 47159012671) == 1 # True

"Текущая реализация хранит массив целочисленных объектов для всех целых чисел от -5 до 256, когда вы создаете int в этом диапазоне, вы фактически просто возвращаете ссылку на существующий объект".

Зачем? Потому что маленькие целые числа чаще используются в циклах. Использование ссылки на существующие объекты вместо создания нового объекта экономит накладные расходы.

Ответ 2

Если вы посмотрите на Objects/longobject.c, который реализует тип int для CPython, вы увидите, что числа между -5 (NSMALLNEGINTS) и 256 (NSMALLPOSINTS - 1) предварительно выделены и кэшированы. Это сделано, чтобы избежать наказания за выделение нескольких ненужных объектов для наиболее часто используемых целых чисел. Это работает, потому что целые числа неизменны: вам не нужно несколько ссылок для представления одного и того же числа.

Ответ 3

Python ничего не знает, пока вы не скажете это. Таким образом, в приведенном выше коде, когда вы инициализируете a и b, вы сохраняете эти значения (в регистре или ОЗУ) и вызываете место для хранения a и b, чтобы вы могли ссылаться на них позже. Если вы сначала не инициализировали переменную, python просто выдаст вам ошибку.

Ответ 4

Зачем?

is немного сбивает с толку:

@ajnLJA-0184 является правильным, но, кроме того, строки также работают хорошо, но когда вы выполняете некоторые операции с ним, но все же те же строки, нет:

>>> a = 'python'
>>> b = 'python'
>>> a is b
True
>>> a = 'pytho' + 'n'
>>> b = 'pythonn'[:-1]
>>> a is b
False
>>> 

Но как ни странно, для целых чисел это не так:

>>> a = 1
>>> b = 1
>>> a is b
True
>>> a = 3*8
>>> b = 4*6
>>> a is b
True
>>> 

Но по той ссылке, которую он дал, там видно, что

>>> a = 257
>>> b = 257
>>> a is b
False
>>> 

Как узнать, будет ли это True или нет?

Хорошо, вот когда id пригодится:

Вот, пожалуйста, просто введите id и две пары, и скажите, что ваш varaible...:

>>> a = 1
>>> b = 1
>>> id(a)
1935522256
>>> id(b)
1935522256
>>> a = 257 # or -6
>>> b = 257 # or -6
>>> id(a)
935705330960
>>> id(b)
935705331216
>>>