What is the difference between "is None" and "== None"
Asked Answered
W

5

552

I recently came across this syntax, I am unaware of the difference.

I would appreciate it if someone could tell me the difference.

Whittaker answered 15/7, 2010 at 16:52 Comment(4)
See Is there a difference between == and is in python?Colt
Does this answer your question? Is there a difference between "==" and "is"?Cockroach
It's unclear if this question is about is vs ==, or about the nature of what exactly None is and how the behaviour differs in either context (the latter is why I ended up here). Based on the vagueness and lack of OP responses... I'm surprised this has so many upvotes. I mean... cmon... the question is not even written in the actual question...Leprechaun
Does this answer your question? Is there any difference between "foo is None" and "foo == None"?Stavros
H
499

The answer is explained here.

To quote:

A class is free to implement comparison any way it chooses, and it can choose to make comparison against None mean something (which actually makes sense; if someone told you to implement the None object from scratch, how else would you get it to compare True against itself?).

Practically-speaking, there is not much difference since custom comparison operators are rare. But you should use is None as a general rule.

Hamster answered 15/7, 2010 at 16:55 Comment(17)
That was an interesting (and short) read. And some useful information into the is v. ==.Dola
Also, is None is a bit (~50%) faster than == None :)Beneficiary
@myusuf3: >>> timeit.Timer('None is None').timeit() | 0.225 | >>> timeit.Timer('None == None').timeit() | 0.328Beneficiary
@myusuf3 You don't really need a proof for that. is is, basically, integer comparison while == is not only resolving references but comparing values which may have mismatching types.Hedelman
Personally, I feel that == should be used in all cases except when either speed matters or you really need to know if you are referring to the same object. == is much simpler and easier to understand. It doesn't leave the reader wondering "why did he use is instead of ==".Overdevelop
One on favour of "is". When a variable can be either None or something that has no meaningful comparison with None. For example, a variable can be a numpy.array or None (my particular case).Tarter
I would like to add to what @TimLudwinski is saying: first, if someone chose to override the equality operator to make None a special case, why would we want to tell them otherwise? Second, "There should be one-- and preferably only one --obvious way to do it." And the obvious way to check if something is equal to something is, well, the equality operator.Hubert
Personally, I find the == None and != None much easier to read than 'is None' and 'is not None' -- it's simply more concise. Imagine in Java, if you had to type in " is not null " in place of " != null" and " is null" in place of " == null"! I would imagine that would get very annoying, very quickly!Glutamate
The truth is we all do it because of the SQL NULL trauma.Demicanton
Numpy uses custom comparison operators and will perform element-wise comparisons for array == True/False, and at some point in the future will do the same for None. "If array == False:" does not work. In the future "if array == None:" won't work either. Custom operators cannot be ignored.Faustofaustus
@Matt Thompson: For Numpy, using "if array is None" still works, though. "Is" checks whether the entire object is None instead of doing element-wise comparison.Belicia
I used to be a hardcore supporter of "use is None unless you have a good reason to do == None", but it was precisely the "what if someone wants to implement a None-like object" case which made me start wondering if actually maybe == None is The Right Way(tm)...Uppermost
You know those hard-to-track-down errors when a line like foo.bar throws a TypeError: NoneType has no attribute "bar" and you're left having to step backwards through the logic and figure out where the None that ended up assigned to foo could have come from. I thought the other day that a magic None object which isn't a singleton but instead carries annotations about where it came from would help that, but that would break is None checks. Basically, when we say is None, we're marrying ourselves to the language implementation/design choice that None is a singleton.Uppermost
@Uppermost Which None should always be singleton, to accomplish what you are referring to, the state could be stored and tracked externally- especially since this feature would be purely for testing, it would be best to prevent it from potentially any unwanted effects on the programs semantics, tho I do see why you would go about it that way. I've always felt that Python's use of None is inspired by Options, a concept from OCaml where either there is Something, or None. None being non-singleton means inherently that it is very well, Something. ocaml-lib.sourceforge.net/doc/Option.htmlMohammed
@Mohammed it is impossible to store the state you'd get from wrapping a None "externally", short of injecting extra code basically at every expression/bytecode which could assign/read/pass values around, while introspecting/recording the names of the variables/attributes/parameters involved. It's all well and good to say that None should be a singleton, but to the extent that it's true, it's also true that the vast majority of code shouldn't be using None, it should be using None-or-a-None-like-wrapper, and incidentally there's a equality operator for that.Uppermost
@Mohammed to rephrase that in terms of types like Option (I agree, None is basically the "nothing" case of an option type) my point here is that the vast majority of code which currently uses None in Python (or Options in most code that has options) would actually be better designed if it used DebugAnnotationMonad<Option<T>> instead, where the DebugAnnotationMonad is a hypothetical mostly-transparent wrapper holding metadata that would be useful for debugging (which a language could even choose to optimize out, like how release builds can strip out assert statements in most languages).Uppermost
@Uppermost Regardless, PEP 0008 does state how Python (regardless of Python implementation) expects None to be compared. That said, it is due to the fact that None is singleton, which as a design feature is a separate discussion. https://peps.python.org/pep-0008/#programming-recommendationsMohammed
C
232
class Foo:
    def __eq__(self, other):
        return True
foo = Foo()

print(foo == None)
# True

print(foo is None)
# False
Cortex answered 15/7, 2010 at 18:38 Comment(2)
See https://mcmap.net/q/37520/-is-there-any-difference-between-quot-foo-is-none-quot-and-quot-foo-none-quot for some interesting comments on this answer.Gibber
This is very good example to show that is None can't be missed, while ==None can be missed with.Limacine
P
69

In this case, they are the same. None is a singleton object (there only ever exists one None).

is checks to see if the object is the same object, while == just checks if they are equivalent.

For example:

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

But since there is only one None, they will always be the same, and is will return True.

p = None
q = None
p is q  # True because they are both pointing to the same "None"
Prairial answered 15/7, 2010 at 16:55 Comment(1)
This answer is not correct, as explained in Ben Hoffstein's answer below https://mcmap.net/q/54317/-what-is-the-difference-between-quot-is-none-quot-and-quot-none-quot/…. x == None may evaluate to True even if x is not None but an instance of some class with its own custom equality operator.Dg
F
58

It depends on what you are comparing to None. Some classes have custom comparison methods that treat == None differently from is None.

In particular the output of a == None does not even have to be boolean !! - a frequent cause of bugs.

For a specific example take a numpy array where the == comparison is implemented elementwise:

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
Fussy answered 13/2, 2020 at 9:32 Comment(1)
I think this is a better answer than the current accepted answer, as it has easy to understand examples.Loanloanda
G
6

If you use numpy,

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

will give you an error when numpy does elementwise comparison.

Geosphere answered 30/10, 2014 at 10:30 Comment(1)
Also: np.array(None) is None : False.Twosided

© 2022 - 2024 — McMap. All rights reserved.