Оператор is
говорит вам, является ли две переменные указывают на тот же объект в памяти. Это редко полезно и часто путают с оператором ==
, который говорит вам, будут ли два объекта «выглядеть одинаково».
Это особенно сбивает с толку при использовании с вещами, такими как короткие строковые литералы, потому что компилятор Python ставит их для повышения эффективности. Другими словами, когда вы пишете "xx"
, компилятор (испускает байт-код) создает один строковый объект в памяти и вызывает все литералы "xx"
, чтобы указать на него. Это объясняет, почему ваши первые два сравнения являются True. Обратите внимание на то, что вы можете получить идентификатор строки, вызвав id
на них, которые (по крайней мере, на CPython, вероятно) их адрес в памяти:
>>> a = "xx"
>>> b = "xx"
>>> id(a)
38646080
>>> id(b)
38646080
>>> a is b
True
>>> a = "x"*10000
>>> b = "x"*10000
>>> id(a)
38938560
>>> id(b)
38993504
>>> a is b
False
Третий том, что компилятор не интернированные строки a
и b
, по какой-либо причине (вероятно, потому, что он недостаточно умен, чтобы заметить, что переменная n
определена один раз, а затем никогда не изменялась).
На самом деле вы можете заставить Python интернировать строки, ну, asking it to. Это даст вам возможность увеличить производительность и может помочь. Это бесполезно.
Мораль: не использовать is
со строковыми литералами. Или int литералы. Или в любом месте, на самом деле это не значит.
Где, черт возьми, люди узнают о 'is', но не о том, как он отличается от' == '? – delnan
Возможный дубликат [Python '==' vs 'is' Сравнение строк, 'иногда не получается, почему?] (Http://stackoverflow.com/questions/1504717/python-vs-is-comparing-strings-is -fails-why-why) – SilentGhost
@SilentGhost: Не совсем так, поскольку это касается темы, когда компиляторы могут неожиданно запускать строки. –