Как 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
>>>