Jaka jest różnica między „is None” i „== None”

324

Ostatnio natrafiłem na tę składnię, nie jestem świadomy różnicy.

Byłbym wdzięczny, gdyby ktoś mógł powiedzieć mi różnicę.

myusuf3
źródło
1
Czy to odpowiada na twoje pytanie? Czy istnieje różnica między „==” a „is”?
czerwca
Nie jest jasne, czy to pytanie dotyczy isvs ==, czy też natury tego, czym dokładnie Nonejest i czym różni się zachowanie w obu kontekstach (to właśnie dlatego skończyłem tutaj). Na podstawie niejasności i braku odpowiedzi OP ... Jestem zaskoczony, że ma tak wiele pozytywnych opinii. Mam na myśli ... cmon ... pytanie nie jest nawet zapisane w prawdziwym pytaniu ...
RTbecard

Odpowiedzi:

291

Odpowiedź wyjaśniono tutaj .

Cytować:

Klasa może zaimplementować porównanie w dowolny sposób i może wybrać porównanie z None, co ma znaczenie (co w rzeczywistości ma sens; jeśli ktoś powiedziałby ci, abyś zaimplementował obiekt None od zera, jak inaczej miałbyś go porównać do wartości True przeciwko sobie?).

Praktycznie rzecz biorąc, nie ma dużej różnicy, ponieważ niestandardowe operatory porównania są rzadkie. Ale powinieneś używać is Nonejako ogólnej zasady.

Ben Hoffstein
źródło
57
Ponadto is Nonejest nieco (~ 50%) szybszy niż == None:)
Nas Banov
26
@ myusuf3: >>> timeit.Timer („None is None”). timeit () | 0,225 | >>> timeit.Timer ('None == None'). timeit () | 0.328
Nas Banov
9
@ myusuf3 Naprawdę nie potrzebujesz na to dowodu. isjest zasadniczo porównaniem liczb całkowitych, podczas gdy ==nie tylko rozwiązuje odwołania, ale porównuje wartości, które mogą mieć typy niezgodne.
Pijusn
4
Jeden opowiada się za „jest”. Gdy zmienną może być None lub coś, co nie ma znaczącego porównania z None. Na przykład zmienną może być numpy.array lub None (mój szczególny przypadek).
Jblasco
3
Chciałbym dodać do tego, co mówi @TimLudwinski: po pierwsze, jeśli ktoś zdecyduje się zastąpić operator równości, aby nikt nie był wyjątkowym przypadkiem, dlaczego mielibyśmy mówić mu inaczej? Po drugie: „Powinien istnieć jeden - a najlepiej tylko jeden - oczywisty sposób na to”. Oczywistym sposobem sprawdzenia, czy coś jest równe, jest operator równości.
Yuval,
162
class Foo:
    def __eq__(self,other):
        return True
foo=Foo()

print(foo==None)
# True

print(foo is None)
# False
unutbu
źródło
56

W tym przypadku są takie same. Nonejest obiektem singletonowym (istnieje tylko jeden None).

is sprawdza, czy obiekt jest tym samym obiektem, a == tylko sprawdza, czy są one równoważne.

Na przykład:

p = [1]
q = [1]
p is q # False because they are not the same actual object
p == q # True because they are equivalent

Ale ponieważ jest tylko jeden None, zawsze będą one takie same i iszwrócą Prawdę.

p = None
q = None
p is q # True because they are both pointing to the same "None"
Donald Miner
źródło
17
Ta odpowiedź jest nieprawidłowa, jak wyjaśniono w odpowiedzi Bena Hoffsteina poniżej stackoverflow.com/questions/3257919/is-none-vs-none/… . x == Nonemoże oceniać, Truenawet jeśli xnie jest Noneto instancja jakiejś klasy z własnym niestandardowym operatorem równości.
maks.
5

Jeśli używasz numpy,

if np.zeros(3)==None: pass

da ci błąd, gdy numpy dokonuje porównania elementarnego

jf328
źródło
3

To zależy od tego, co porównujesz do Brak. Niektóre klasy mają niestandardowe metody porównywania, które traktują == Noneinaczej niż is None.

W szczególności wynik a == None nie musi być nawet logiczny !! - częsta przyczyna błędów.

Na konkretny przykład weź tablicę numpy, w której ==porównanie jest implementowane elementarnie:

import numpy as np
a = np.zeros(3) # now a is array([0., 0., 0.])
a == None #compares elementwise, outputs array([False, False, False]), i.e. not boolean!!!
a is None #compares object to object, outputs False
PGlivi
źródło