is confronta l'identità degli oggetti (cioè, se le variabili puntano alla stessa area di memoria).== (operatore eq) confronta i valori, cioè se gli oggetti sono uguali in termini di contenuto.is dovrebbe essere usato per confrontare specificamente l'identità (ad esempio, con None o per oggetti singleton), e non per controllare l'uguaglianza dei valori.
Esempio:
a = [1, 2, 3] b = [1, 2, 3] print(a == b) # True print(a is b) # False c = None d = None print(c is d) # True
Quando si lavora con piccoli numeri interi o stringhe, l'interprete potrebbe utilizzare "interning" (oggetti memorizzati nella cache), il che a volte rende is vero per valori uguali, ma ciò non dovrebbe essere utilizzato nella logica del programma.
Domanda: Cosa stamperà il seguente codice?
a = 256 b = 256 print(a is b) c = 257 d = 257 print(c is d)Perché?
Risposta:
Per i valori da -5 a 256, Python utilizza un pool di numeri interi. I valori in questo intervallo puntano sempre agli stessi oggetti, quindi a is b restituirà True. 257 è già al di fuori del pool, quindi c is d sarà False (gli oggetti sono indipendenti).
Storia
In un microservizio, il confronto di uguaglianza delle stringhe è stato effettuato con is invece di ==. A causa delle ottimizzazioni dell'interprete, il programma funzionava "stabilmente" nei test, ma ha iniziato a guastarsi dopo la ricompilazione o altre modifiche all'ambiente.
Uno sviluppatore ha usato l'operatore is invece di == per confrontare numeri. Questo ha funzionato per numeri piccoli (grazie al pool), ma per numeri grandi ha causato guasti e risultati imprevedibili, causando un funzionamento errato dei calcoli.
Nel progetto del sistema di autorizzazione, è stato controllato il JSON ricevuto con is None (corretto), e poi per analogia si è fatto lo stesso per le stringhe: if status is "ok". Questo si è rivelato un errore: a volte la condizione non veniva soddisfatta, portando a una logica errata nel trattamento dei dati.