Это ошибка?Переменные - это идентичные ссылки на одну и ту же строку в этом примере (Python) - PullRequest
8 голосов
/ 12 ноября 2010

Это для 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

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

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

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

Ответы [ 3 ]

10 голосов
/ 12 ноября 2010

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

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

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

1 голос
/ 12 ноября 2010

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

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

0 голосов
/ 12 ноября 2010

Это должно быть больше комментарием к ответу Глин, но я пока не могу комментировать. Я провел несколько тестов непосредственно на интерпретаторе 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), но это также может быть связано со временем, когда эти ссылки на id не используются, так как можно видеть в том, что я пометил как число (2), давая различные ссылки на идентификаторы в зависимости от того, как долго этот идентификатор не использовался. Я просто нахожу это любопытным и думал опубликовать его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...