C'è differenza tra “pippo è Nessuno” e “pippo = = ”None"?
-
09-06-2019 - |
Domanda
Che differenza c'è tra:
if foo is None: pass
e
if foo == None: pass
La convenzione che ho visto nella maggior parte del codice Python (e il codice che io stesso ho scritto) è il primo, ma recentemente ho trovato il codice che usa il secondo.Nessuno è un esempio (e l'unica istanza, IIRC) di NoneType, quindi non ci importa, giusto?Vi sono circostanze in cui potrebbe?
Soluzione
is
restituisce sempre True
se si confronta la stessa istanza di oggetto
Considerando che ==
è, in definitiva, determinata dalla __eq__()
metodo
cioè
>>> class Foo(object):
def __eq__(self, other):
return True
>>> f = Foo()
>>> f == None
True
>>> f is None
False
Altri suggerimenti
Si consiglia di leggere questo identità di oggetto e di equivalenza.
L'istruzione 'è' viene utilizzato per identità di oggetto, controlla se gli oggetti si riferiscono alla stessa istanza (stesso indirizzo di memoria).
E '==' dichiarazione si riferisce all'uguaglianza (stesso valore).
Una parola di cautela:
if foo:
# do something
È non esattamente la stessa:
if x is not None:
# do something
Il primo è un valore booleano test e in grado di valutare per falso in contesti diversi.Ci sono un certo numero di cose che rappresentano le false in un valore booleano test per esempio i contenitori vuoti, i valori booleani.Nessuno, inoltre, restituisce false in questa situazione, ma le altre cose non troppo.
(ob1 is ob2)
pari a (id(ob1) == id(ob2))
Il motivo foo is None
è il modo preferito è che si potrebbe essere la gestione di un oggetto che definisce il proprio __eq__
, e che definisce l'oggetto per essere uguale a Nessuno.Quindi, usare sempre foo is None
se hai bisogno di vedere se, infatti, None
.
Non c'è nessuna differenza, perché gli oggetti che sono identici sarà ovviamente uguale.Tuttavia, PEP 8 chiaramente si dovrebbe usare is
:
Confronti di singleton come Nessuno dovrebbe sempre essere fatto con è o non è, non gli operatori di uguaglianza.
is
prove di identità, non la parità.Per la vostra dichiarazione foo is none
, Python confronta semplicemente l'indirizzo di memoria di oggetti.Significa che ti stai chiedendo alla domanda "ho due nomi per lo stesso oggetto?"
==
d'altra parte i test per l'uguaglianza, come determinato dal __eq__()
metodo.Non si preoccupa di identità.
In [102]: x, y, z = 2, 2, 2.0
In [103]: id(x), id(y), id(z)
Out[103]: (38641984, 38641984, 48420880)
In [104]: x is y
Out[104]: True
In [105]: x == y
Out[105]: True
In [106]: x is z
Out[106]: False
In [107]: x == z
Out[107]: True
None
è un singleton operatore.Così None is None
è sempre vero.
In [101]: None is None
Out[101]: True
Per Nessuno, non dovrebbe essere una differenza tra uguaglianza (==) e identità (è).Il NoneType probabilmente restituisce identità per l'uguaglianza.Siccome non è l'unico esempio che si può fare di NoneType (credo che questo sia vero), le due operazioni sono le stesse.In caso di altri tipi questo non è sempre il caso.Per esempio:
list1 = [1, 2, 3]
list2 = [1, 2, 3]
if list1==list2: print "Equal"
if list1 is list2: print "Same"
Questo sarebbe di stampa "Pari" dal momento che le liste di un'operazione di confronto che non è l'impostazione predefinita di un ritorno di identità.
@Jason:
Mi consiglia di utilizzare qualcosa di più lungo le linee di
if foo: #foo isn't None else: #foo is None
Non mi piace usare il "se pippo:" se pippo rappresenta davvero un valore booleano (es.0 o 1).Se pippo è una stringa o un oggetto o qualcosa d'altro, "se pippo:" potrebbe funzionare, ma sembra un pigro di scelta rapida per me.Se si sta controllando per vedere se x è Nessuno, dire "se x è Nessuno:".
Qualche dettaglio in più:
Il
is
clausola in realtà controlla se i dueobject
s sono allo stesso posizione di memoria o non.io.e se entrambi puntano allo stesso posizione di memoria e di avere la stessaid
.Come conseguenza di 1,
is
garantisce sia, o non, i due lessicale rappresentatoobject
s sono identici attributi attributi di attributi...) o nonLa creazione di istanze di tipi primitivi come
bool
,int
,string
(con qualche eccezione),NoneType
avendo lo stesso valore sarà sempre nella stessa posizione di memoria.
E. g.
>>> int(1) is int(1)
True
>>> str("abcd") is str("abcd")
True
>>> bool(1) is bool(2)
True
>>> bool(0) is bool(0)
True
>>> bool(0)
False
>>> bool(1)
True
E dal momento che NoneType
può avere una sola istanza di se stesso in python "look-up", tabella, pertanto, il primo e il secondo sono più di uno stile di programmazione dello sviluppatore che ha scritto il codice(forse per coerenza) piuttosto che avere qualche sottile logico motivo in più per scegliere uno sopra l'altro.
John Machin, la conclusione è che None
è un singleton è una conclusione sostenuta dal presente codice.
>>> x = None
>>> y = None
>>> x == y
True
>>> x is y
True
>>>
Dal None
è un singleton, x == None
e x is None
avrebbe lo stesso risultato.Tuttavia, a mio parere estetico, x == None
è la cosa migliore.
a is b # returns true if they a and b are true alias
a == b # returns true if they are true alias or they have values that are deemed equivalence
a = [1,3,4]
b = a[:] #creating copy of list
a is b # if gives false
False
a == b # gives true
True