Это ошибка? Переменные – это одинаковые ссылки на одну и ту же строку в этом примере (Python)

Это для Python 2.6.

Я не мог понять, почему a и b идентичны:

>>> a = "some_string" >>> b = "some_string" >>> a is b True 

Но если в строке есть пробел, это не так:

 >>> a = "some string" >>> b = "some string" >>> a is b False 

Если это нормальное поведение, кто-то может объяснить, что происходит.

Редактировать: Отказ от ответственности! Это не используется для проверки равенства. Я действительно хотел объяснить кому-то еще, что «есть» – это только проверка личности, а не равенства. И из документации я понял, что создаваемые таким образом ссылки будут разными, что новая строка будет создаваться каждый раз. Самый первый пример, который я дал, отбросил меня, когда я не смог доказать свою точку зрения!

Редактирование: я понимаю, что это не ошибка, и интернирование было для меня новой концепцией. Это кажется хорошим объяснением.

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

Если он решает ставить строку, то оба будут ссылаться на один и тот же экземпляр строки. Если это не так, это создаст две отдельные строки, которые имеют одинаковое содержимое.

В общем, вам не нужно беспокоиться о том, происходит ли это или нет; вы обычно хотите проверить равенство, a == b , а не те ли они один и тот же объект, a is b .

TIM PETERS SAID: Извините, единственная ошибка, которую я вижу здесь, – это код, который вы опубликовали, используя «is», чтобы попытаться определить, равны ли две строки. «есть» тесты для идентификации объекта, а не для равенства, и не являются ли два неизменяемых объекта на самом деле одним и тем же объектом, в общем, не определяемым Python. Вы должны использовать «==» для проверки двух строк для равенства. Единственный раз, когда можно использовать «is» для этой цели, это когда вы явно интерполировали все сопоставляемые строки (используя встроенную функцию intern ()).

отсюда: http://mail.python.org/pipermail/python-bugs-list/2004-December/026772.html

Это должно быть скорее комментарий к ответу Глин, но я пока не могу комментировать комментарии. Я проверил некоторые тесты непосредственно на интерпретаторе Python, и я увидел некоторое интересное поведение. Согласно Гленну, интерпретатор рассматривает записи как отдельные «файлы», и они не используют таблицу строк, если они хранятся для дальнейшего использования. Вот что я запускаю:

 >>> a="some_string" >>> b="some_string" >>> id(a) 2146597048 >>> id(b) 2146597048 >>> a="some string" >>> b="some string" >>> id(a) 2146597128 >>> id(b) 2146597088 >>> c="some string" <-----(1) >>> d="some string" >>> id(c) 2146597208 <-----(1) >>> a="some_string" >>> b="some_string" >>> id(a) 2146597248 <---- waited a few minutes >>> c="some_string" >>> d="some_string" >>> id(d) 2146597248 <---- still same id after a few min >>> b="some string" >>> id(b) 2146597288 >>> b="some_string" <---(2) >>> id(b) 2146597248 <---(2) >>> a="some" >>> b="some" >>> c="some" >>> d="some" <---(2) lost all references >>> id(a) 2146601728 >>> a="some_string" <---(2) >>> id(a) 2146597248 <---(2) returns same old one after mere seconds >>> a="some" >>> id(a) 2146601728 <---(2) Waited a few minutes >>> a="some_string" <---- (1) >>> id(a) 2146597208 <---- (1) Reused a "different" id after a few minutes 

Похоже, что некоторые ссылки на идентификаторы могут быть повторно использованы после того, как исходные ссылки будут потеряны и больше не «используются» (1), но также могут быть связаны со временем, когда эти ссылки на идентификаторы не используются, как вы можете видеть в что я обозначил как число (2), давая разные ссылки id в зависимости от того, как долго этот идентификатор не использовался. Я просто нахожу это любопытным и думал о его публикации.