Un altro duplicato chiedeva perché due stringhe uguali in genere non sono identiche, il che non è davvero risposto qui:
>>> x = 'a'
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False
Allora, perché non sono la stessa stringa? Soprattutto dato questo:
>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True
Rimandiamo un po 'la seconda parte. Come potrebbe essere vero il primo?
L'interprete dovrebbe avere una "tabella interna", una tabella che associa i valori delle stringhe agli oggetti stringa, così ogni volta che provi a creare una nuova stringa con il contenuto 'abc'
, ritorna lo stesso oggetto. Wikipedia ha una discussione più dettagliata su come funziona lo stage.
E Python ha una tabella interna di stringhe; puoi internare manualmente le stringhe con il sys.intern
metodo.
In effetti, Python può internare automaticamente qualsiasi tipo immutabile, ma non è obbligato a farlo. Diverse implementazioni interneranno valori diversi.
CPython (l'implementazione che stai usando se non sai quale implementazione stai usando) auto-interns piccoli interi e alcuni singleton speciali come False
, ma non stringhe (o numeri interi grandi, o piccole tuple o qualsiasi altra cosa). Puoi vederlo abbastanza facilmente:
>>> a = 0
>>> a += 1
>>> b = 1
>>> a is b
True
>>> a = False
>>> a = not a
>>> b = True
a is b
True
>>> a = 1000
>>> a += 1
>>> b = 1001
>>> a is b
False
OK, ma perché erano z
e w
identici?
Non è l'interprete che esegue automaticamente l'internamento, sono i valori di ripiegamento del compilatore.
Se la stessa stringa di compilazione appare due volte nello stesso modulo (che cosa esattamente questo significa è difficile da definire, non è la stessa cosa di un letterale di stringa, perché r'abc'
, 'abc'
e 'a' 'b' 'c'
sono tutte letterali diverse ma la stessa stringa, ma facile da capire intuitivamente), il compilatore creerà solo un'istanza della stringa, con due riferimenti.
In effetti, il compilatore può andare anche oltre: 'ab' + 'c'
può essere convertito in 'abc'
dall'ottimizzatore, nel qual caso può essere piegato insieme a una 'abc'
costante nello stesso modulo.
Di nuovo, questo è qualcosa che Python è consentito ma non è tenuto a fare. Ma in questo caso, CPython piega sempre piccole stringhe (e anche, ad esempio, piccole tuple). (Sebbene il compilatore istruzione per istruzione dell'interprete interattivo non esegua la stessa ottimizzazione del compilatore modulo alla volta, quindi non vedrai esattamente gli stessi risultati in modo interattivo.)
Allora, cosa dovresti fare al riguardo come programmatore?
Beh ... niente. Non hai quasi mai motivo di preoccuparti se due valori immutabili sono identici. Se vuoi sapere quando puoi usare a is b
invece di a == b
, stai facendo la domanda sbagliata. Basta usare sempre a == b
tranne in due casi:
- Per confronti più leggibili con i valori singleton come
x is None
.
- Per i valori modificabili, quando è necessario sapere se la modifica
x
influirà su y
.