Ho cercato nel Web e ho accumulato domande di overflow ma non sono riuscito a trovare una risposta a questa domanda. L'osservazione che ho fatto è che in Python 2.7.3, se assegni a due variabili la stessa stringa di carattere singolo, ad es.In quali circostanze le stringhe uguali condividono lo stesso riferimento?
>>> a = 'a'
>>> b = 'a'
>>> c = ' '
>>> d = ' '
Poi le variabili si condividono la stessa di riferimento:
>>> a is b
True
>>> c is d
True
Questo vale anche per alcune stringhe più lunghe:
>>> a = 'abc'
>>> b = 'abc'
>>> a is b
True
>>> ' ' is ' '
True
>>> ' ' * 1 is ' ' * 1
True
Tuttavia, ci sono un sacco di casi in cui il riferimento è (non inaspettatamente) non condiviso:
>>> a = 'a c'
>>> b = 'a c'
>>> a is b
False
>>> c = ' '
>>> d = ' '
>>> c is d
False
>>> ' ' * 2 is ' ' * 2
False
Qualcuno può spiegare la ragione di ciò?
Sospetto che ci possano essere delle semplificazioni/sostituzioni eseguite dall'interprete e/o un meccanismo di memorizzazione nella cache che faccia uso del fatto che le stringhe Python sono immutabili da ottimizzare in alcuni casi speciali, ma che ne so? Ho provato a fare delle copie profonde delle stringhe usando il costruttore str e la funzione copy.deepcopy ma le stringhe condividono ancora i riferimenti in modo incoerente.
Il motivo per cui ho problemi con questo è perché controllo la disuguaglianza dei riferimenti alle stringhe in alcuni test di unità che sto scrivendo per metodi clone di classi python di nuovo stile.
Grazie per la risposta, sembra che lei ha ragione in merito a tale stringhe in codice sorgente sono sempre internati (stringhe che non sono letterali non hanno questa proprietà). Quindi, i miei esempi sono validi solo quando si scrive nell'interprete interattivo python. Sto usando CPython e la tua risposta conferma alcuni dei miei sospetti. Sono d'accordo che l'operatore == dovrebbe essere usato per controllare le stringhe per l'uguaglianza. C'è un modo elegante per controllare dove è stato inizializzato un attributo o dovrei semplicemente evitare questo tipo di test? – EriF89
@ EriF89: cosa significa controllare "dove è stato inizializzato un attributo"? E come importa? –
Dato che sto scrivendo dei test per assicurarmi che i riferimenti agli attributi non siano condivisi in modo improprio tra gli oggetti clonati, vorrei un modo generico per verificare che le modifiche in uno degli oggetti non trapelino nell'altra. Ho pensato che l'operatore is avrebbe fatto questo, ma dal momento che i riferimenti sono condivisi, suppongo di dover assegnare nuovi valori agli attributi di uno degli oggetti, e controllare che non siano cambiati nell'altro, invece. – EriF89