Python Nessuno confronto: dovrei usare "is" o ==?


217

Il mio editor mi avverte quando confronto my_var == None, ma nessun avviso quando lo uso my_var is None.

Ho fatto un test nella shell Python e ho determinato che entrambe sono sintassi valide, ma il mio editor sembra dire che my_var is Noneè la preferita.

È questo il caso e, in caso affermativo, perché?


7
PEP 8 dice da qualche parte che dovresti confrontare con i singleton usando is- python.org/dev/peps/pep-0008/#programming-recommendations
Volatility

2
Quel poster parla di Python 3 e la mia domanda riguarda Python 2.x. Non sono sicuro che questa sia una differenza abbastanza grande da garantire che entrambi restino, ma ho modificato la domanda per includerla per ogni evenienza.
Clay Wardell

2
Non credo che questa domanda sia davvero un duplicato. L'altro riguardava == vs è in generale, questo riguarda Nessuno in particolare.
IJ Kennedy

Risposte:


266

Sommario:

Da utilizzare isquando si desidera verificare l' identità di un oggetto (ad es. Verificare se lo varè None). Da utilizzare ==quando si desidera verificare l' uguaglianza (ad es. È varuguale a 3?).

Spiegazione:

Puoi avere classi personalizzate in cui my_var == NonetorneràTrue

per esempio:

class Negator(object):
    def __eq__(self,other):
        return not other

thing = Negator()
print thing == None    #True
print thing is None    #False

isverifica l' identità dell'oggetto . C'è solo 1 oggetto None, quindi quando lo fai my_var is None, stai controllando se sono effettivamente lo stesso oggetto (non solo oggetti equivalenti )

In altre parole, ==è un controllo dell'equivalenza (che è definito da oggetto a oggetto) mentre iscontrolla l'identità dell'oggetto:

lst = [1,2,3]
lst == lst[:]  # This is True since the lists are "equivalent"
lst is lst[:]  # This is False since they're actually different objects

27
Quando is Nonedifferisce da == None?
Blender

13
@ Blender Nel caso menzionato. __eq__può essere definito in qualsiasi modo, ma il comportamento di isnon può essere modificato così facilmente.
Lev Levitsky

5
@ LevLevitsky: Uno degli esempi di utilizzo di Mython è stato "l'estensione dei protocolli in modo che qualsiasi operatore possa essere sovraccaricato, anche is". Dopo un commento sugli elenchi, lo ha cambiato in "... anche is(ma solo se sei pazzo)".
abarnert

1
+1, ma sarebbe ancora meglio se questa risposta includesse il riferimento PEP 8 che gli altri fanno (oltre a spiegare perché la decisione dietro PEP 8 ha senso, cosa che già fa).
abarnert

3
@abarnert - Non sapevo nemmeno che PEP 8 avesse fatto una raccomandazione qui. Il punto è che sono operatori diversi che fanno cose diverse. Potrebbero esserci casi in cui object == Noneeffettivamente è l'idioma corretto (anche se non riesco a pensare a nessuno dalla parte superiore della mia testa). Hai solo bisogno di sapere cosa stai facendo.
mgilson

132

isè generalmente preferito quando si confrontano oggetti arbitrari a singleton come Noneperché è più veloce e più prevedibile. isconfronta sempre in base all'identità dell'oggetto, mentre ciò ==che farà dipende dal tipo esatto degli operandi e anche dal loro ordine.

Questa raccomandazione è supportata da PEP 8 , che afferma esplicitamente che "i confronti con singoli come None dovrebbero essere sempre eseguiti con iso is not, mai con gli operatori di uguaglianza".


6
Grazie per aver postato questo; la risposta accettata fa alcuni punti interessanti, ma la tua risponde alla domanda in modo molto più diretto.
Luke Davis

Sembra strano fare affidamento su ciò che è essenzialmente un dettaglio di implementazione. Perché dovrei preoccuparmi di quante istanze di NoneType ci sono?
Ballpoint

@BallpointBen Perché non è un dettaglio di implementazione, c'è solo un Noneoggetto sotto la costante globale None. Semmai, NoneTypeè un dettaglio di implementazione perché il Nonesingleton deve avere un tipo. (Il fatto che non sia possibile creare istanze di questo tipo è una buona indicazione che la sua unica istanza è intesa come singleton.)
user4815162342

@BallpointBen Penso che il punto chiave sia che Python possiede un forte concetto di identità dell'oggetto. Se vuoi controllare se un oggetto è uguale a None, usa tutti i mezzi obj == None. Se vuoi controllare se un oggetto è None , usa obj is None. Il punto della raccomandazione PEP 8 (e di questa risposta) è che la maggior parte delle persone desidera quest'ultima quando vogliono controllare Nessuno, e sembra anche che sia più veloce e più chiara.
user4815162342

Noneè anche diverso dagli oggetti memorizzati nella cache come 0e altri piccoli numeri interi, dove la memorizzazione nella cache è davvero un dettaglio di implementazione. La differenza è che un numero intero ha un valore intrinseco che dà le sue proprietà e può essere calcolato. D'altra parte, Nonenon ha alcuno stato, è solo la sua identità che conta e lo rende speciale.
user4815162342

11

PEP 8 definisce che è meglio usare l' isoperatore quando si confrontano i singleton.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.