Почему добавление точки с запятой в Python меняет результат?

Я нашел странное поведение с точкой с запятой ";" в Python.

>>> x=20000;y=20000
>>> x is y
True
>>> x=20000
>>> y=20000
>>> x is y
False
>>> x=20000;
>>> y=20000
>>> x is y
False

Почему первый тест возвращает "True", а остальные возвращают "False"? Моя версия Python - 3.6.5.

Ответы

Ответ 1

В интерактивном интерпретаторе первая строка с двумя столбцами считывается и оценивается за один проход. Таким образом, интерпретатор признает, что 20000 - это одно и то же неизменяемое значение int в каждом присваивании, и поэтому (оно не обязательно, но делает) делает x и y ссылками на один и тот же объект.

Важно то, что это просто оптимизация, которую выбирает интерактивный интерпретатор; это не то, что гарантируется языком или каким-то особым свойством ; который объединяет два утверждения в один.

В следующих двух примерах, к моменту, когда y=20000 считывается и оценивается, x=20000 (с или без двоеточия) уже оценивается и забывается. Поскольку 20000 не находится в диапазоне (-5 до 257) предварительно выделенных значений int, CPython не пытается найти еще один экземпляр из 20000 уже в памяти; он просто создает новую для y.

Ответ 2

Оператор is проверяет, являются ли два значения одним и тем же объектом в памяти. Он не предназначен для проверки на равенство. Для того, что стоит, вы могли бы рассмотреть тот факт, что он иногда возвращает True а иногда и False чтобы быть удачей (даже если это не так).

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

$ cat test.py
x = 200000; y = 200000
print(x is y)

xx = 200000
yy = 200000
print(xx is yy)

$ python test.py
True
True

Или у вас есть другой пример:

>>> x = 50 + 50; y = 50 + 50
>>> x is y
True
>>> x = 5000 + 5000; y = 5000 + 5000
>>> x is y
False

Это происходит потому, что интерпретатор кэширует небольшие числа, поэтому они всегда являются одним и тем же объектом, но не для больших чисел, поэтому оба дополнения во втором случае создают новый объект 10000. Это не имеет ничего общего с точкой с запятой.