Разное поведение в python script и python в режиме ожидания?

В режиме ожидания python:

>>> a=1.1
>>> b=1.1
>>> a is b
False

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

$cat t.py
a=1.1
b=1.1
print a is b
$python t.py
True

Почему это произошло? Я знаю, что is сравнивает id двух объектов, поэтому почему идентификаторы двух объектов одинаковы/уникальны в python script/idle?

Я также обнаружил, что если я использую небольшой int, например 1, вместо 1.1, результат будет таким же как в python script, так и в режиме ожидания python. Почему у маленьких int и small float было другое поведение?

Я использую CPython 2.7.5.

Ответ 1

Когда Python выполняет файл script, сначала обрабатывается весь файл. Вы можете заметить, что когда вы вводите синтаксическую ошибку где-то: независимо от того, где она находится, это предотвратит выполнение любой строки.

Итак, поскольку Python сначала анализирует файл, литералы могут быть загружены эффективно в память. Поскольку Python знает, что они являются постоянными, все переменные, которые представляют эти постоянные значения, могут указывать на один и тот же объект в памяти. Таким образом, объект является общим.

Это работает для int и floats, но даже для строк; даже если есть постоянное выражение, которое необходимо оценить сначала:

a = "foo"
b = "foo"
c = "fo" + "o"
print(a is b)
print(a is c)

Теперь в IDLE поведение совсем другое: в качестве интерактивного интерпретатора IDLE выполняет каждую строку отдельно. Таким образом, a = 1.1 и b = 1.1 выполняются в разделенных контекстах, что делает невозможным (или просто очень сложно) понять, что они оба имеют одно и то же значение константного литерала и могут совместно использовать память. Поэтому вместо этого интерпретатор будет выделять два разных объекта, что приведет к сбою проверки идентификатора с помощью is.

Для небольших целых чисел ситуация немного отличается. Поскольку они часто используются, CPython сохраняет набор целых чисел (в диапазоне от -5 до 256) статически и делает каждое значение этих точек одним и тем же объектом int. Вот почему вы получаете другой результат для небольших целых чисел, чем для любого другого объекта. См. Также следующие вопросы: