Как Python узнает значения, уже хранящиеся в его памяти? - PullRequest
10 голосов
/ 19 апреля 2019

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

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

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

Ответы [ 3 ]

13 голосов
/ 19 апреля 2019

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 в этом диапазоне, вы фактически просто получаете ссылку на существующуюобъект. ”

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

5 голосов
/ 19 апреля 2019

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

0 голосов
/ 19 апреля 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...