Почему добавление точки с запятой в 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
. Это не имеет ничего общего с точкой с запятой.