Operator is
powie Ci czy dwóch zmiennych punktowych do tego samego obiektu w pamięci. Jest rzadko przydatny i często mylony z operatorem ==
, który mówi, czy dwa obiekty "wyglądają tak samo".
Jest to szczególnie mylące, gdy używa się go z krótkimi literałami literowymi, ponieważ kompilator Pythona umieszcza je w celu zwiększenia wydajności. Innymi słowy, podczas pisania "xx"
kompilator (emituje kod bajtowy) tworzy jeden obiekt typu string w pamięci i powoduje, że wszystkie literały "xx"
wskazują na to. To tłumaczy, dlaczego twoje pierwsze dwa porównania są prawdziwe. Zauważ, że można uzyskać identyfikator strun poprzez wywołanie id
na nich, które (przynajmniej na CPython jest prawdopodobnie) ich adresów w pamięci:
>>> 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
Trzeci jest, ponieważ kompilator nie został internowany struny a
i b
, z dowolnego powodu (prawdopodobnie dlatego, że nie jest wystarczająco inteligentny, aby zauważyć, że zmienna n
jest zdefiniowana raz, a następnie nigdy nie jest modyfikowana).
W rzeczywistości można wymusić Python na strunach przez, no, asking it to. Zapewni to zwiększenie wydajności i może pomóc. To prawdopodobnie bezużyteczne.
Moralne: nie używaj is
z literałami ciągów. Lub int literały. Albo gdziekolwiek nie masz na myśli tego, naprawdę.
Gdzie do cholery ludzie dowiadują się o "jest", ale nie o tym, jak to się różni od '=='? – delnan
Możliwy duplikat [Python '==' vs 'is' porównywanie ciągów znaków 'czasami kończy się niepowodzeniem, dlaczego?] (Http://stackoverflow.com/questions/1504717/python-vs-is-comparing-strings-is -fails-czasami-dlaczego) – SilentGhost
@SilentGhost: Niezupełnie, ponieważ dotyczy to tematu, kiedy kompilatory mogą niespodziewanie internować ciągi. –