Целочисленное кэширование для чисел больше 256 и меньше -5 - PullRequest
0 голосов
/ 06 ноября 2018

Я знаю, что в python есть концепция маленьких целых чисел, представляющих собой числа от -5 до 256, и если две переменные присваивают одинаковые числа в этом диапазоне, они обе будут использовать один и тот же базовый объект.

Из документации Python,

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS           257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS           5
#endif

/ * Маленькие целые числа предварительно расположены в этом массиве, чтобы они могли быть общим. Предварительно выделенные целые числа диапазон от -NSMALLNEGINTS (включительно) до NSMALLPOSINTS (не включительно). * /

Также объяснил здесь,

Текущая реализация хранит массив целочисленных объектов для всех целые числа от -5 до 256, когда вы создаете int в этом диапазоне, вы на самом деле просто вернуть ссылку на существующий объект. Так что должно быть возможно изменить значение 1. Я подозреваю, что поведение Python в этом случае не определен. : -)

* * Пример тысяча двадцать-один, * * 1 022
a = 255
b = 255
print(id(a))
print(id(b))

дает тот же идентификатор,

1561854394096
1561854394096

Что имеет смысл, а также объяснено в этом ответе, Оператор «is» ведет себя неожиданно с целыми числами

Если два числа меньше -5, они также должны иметь разные идентификаторы следующим образом:

a = -6
b = -6
print(id(a))
print(id(b))

дает,

2827426032208
2827426032272

пока это имеет смысл,

Но любое число больше 256 должно иметь другое значение id,

Это должно вернуть разные идентификаторы,

a = 257
b = 257
print(id(a))
print(id(b))

Но это не

2177675280112
2177675280112

Даже когда я использую очень большое целое число, идентификаторы одинаковы,

a = 2571299123876321621378
b = 2571299123876321621378
print(id(a))
print(id(b))

дает мне,

1956826139184
1956826139184

Может кто-нибудь сказать мне, почему числа больше 256 имеют одинаковые идентификаторы, хотя в коде Python диапазон составляет от -5 до 257 (не включительно)

EDIT:

Я пытался использовать PyCharm с Python 2.7 и 3.6. Также попробовал на PythonTutor.com

1 Ответ

0 голосов
/ 06 ноября 2018

На мятном Python 3.6.3 (также 2) я не могу воспроизвести. Я предполагаю, что PyCharm или pythontutor оборачивают цикл во что-то перед интерпретацией - так как это не открытый код, мы не можем видеть внутренности, поэтому я не могу проверить. Причина, по которой я думаю, что это правда, в то время как (все ниже - мята Python 3):

>>> x=2571299123876321621378
>>> y=2571299123876321621378
>>> print(id(x),id(y))
140671727739528 140671727739808

Вы можете иметь это:

>>> def bla():
...  x=2571299123876321621378
...  y=2571299123876321621378
...  id(x)
...  print(id(x),id(y))
...
>>> bla()
140671727742528 140671727742528

, поэтому обертывание двух целых чисел во что-то, что может скомпилировать интерпретатор, допускает эти дополнительные оптимизации - например, использование одной и той же константы для обоих определений. Обратите внимание, что это также ограничено:

>>> def bla():
...  x=2571299123876321621378
...  y=2571299123876321621378
...  print(id(x),id(y))
...  x+=1
...  y+=1
...  print(id(x),id(y))
...
>>> bla()
140671727755592 140671727755592
140671728111088 140671728108808

У меня не было бы кода, который в любом случае зависит от этого - гарантия только от -5 до 256.

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