Почему бы Python не оценить s1+"g" и не понять, что это то же самое, что s2 и указать на тот же адрес? Что на самом деле происходит в этом последнем блоке, чтобы он вернулFalse?
Переведено автоматически
Ответ 1
Это зависит от конкретной реализации, но ваш интерпретатор, вероятно, интернирует константы времени компиляции, но не результаты выражений во время выполнения.
В дальнейшем используется CPython 3.9.0+.
Во втором примере выражение "strin"+"g" вычисляется во время компиляции и заменяется на "string". Это приводит к тому, что первые два примера ведут себя одинаково.
Если мы изучим байт-коды, то увидим, что они в точности совпадают:
Этот байт-код был получен с помощью (который выводит еще несколько строк перед приведенным выше, и эти строки точно такие же, как в первом блоке байт-кодов, приведенном выше):
Кроме того, Python 3.9 выводит предупреждение для последних двух приведенных выше инструкций:
SyntaxWarning: "is" с литералом. Вы имели в виду "=="?
Ответ 2
Пример 1
>>> x = "123" >>> y = "123" >>> x == y True >>> x is y True >>> id(x) 50986112 >>> id(y) 50986112
Пример 2
>>> x = "12" >>> y = "123" >>> x = x + "3" >>> x is y False >>> x == y True
Теперь ваш вопрос заключается в том, почему идентификатор одинаков в случае 1, а не в случае 2.
В случае 1 вы назначили строковый литерал "123" для x и y.
Поскольку string неизменяемы, интерпретатору имеет смысл сохранить строковый литерал только один раз и указать все переменные на один и тот же объект. Следовательно, вы видите идентификатор как идентичный.
В случае 2 вы изменяете x с помощью конкатенации. Оба x и y имеют одинаковые значения, но не одинаковые идентификаторы. Оба указывают на разные объекты в памяти. Следовательно, они возвращают разные операторы id и isFalse