tags:

views:

3249

answers:

8

Is there any difference between:

if foo is None: pass

and

if foo == None: pass

The convention that I've seen in most Python code (and the code I myself write) is the former, but I recently came across code which uses the latter. None is an instance (and the only instance, IIRC) of NoneType, so it shouldn't matter, right? Are there any circumstances in which it might?

+102  A: 

is always returns True if it compares the same object instance

Whereas == is ultimately determined by the __eq__() method

i.e.


>>> class foo(object):
       def __eq__(self, other):
           return True

>>> f = foo()
>>> f == None
True
>>> f is None
False
Brendan
You may want to add that None is a singleton so "None is None" is always True.
e-satis
+26  A: 

You may want to read this object identity and equivalence.

The statement 'is' is use for object identity, it checks if objects refer to the same instance (same address in memory).

And the '==' statement refers to equality (same value).

borrego
+3  A: 

For None there shouldn't be a difference between equality (==) and identity (is). The NoneType probably returns identity for equality. Since None is the only instance you can make of NoneType (I think this is true), the two operations are the same. In the case of other types this is not always the case. For example:

list1 = [1, 2, 3]
list2 = [1, 2, 3]
if list1==list2: print "Equal"
if list1 is list2: print "Same"

This would print "Equal" since lists have a comparison operation that is not the default returning of identity.

Stephen Pellicer
+1  A: 

@Jason:

I recommend using something more along the lines of

if foo:
    #foo isn't None
else:
    #foo is None

I don't like using "if foo:" unless foo truly represents a boolean value (i.e. 0 or 1). If foo is a string or an object or something else, "if foo:" may work, but it looks like a lazy shortcut to me. If you're checking to see if x is None, say "if x is None:".

Graeme Perrow
Checking for empty strings/lists with "if var" is the preferred way. Boolean conversion is well defined, and it is less code that even performs better. No reason to do "if len(mylist) == 0" for example.
truppo
+6  A: 

A word of caution:

if foo: # do something

Is not exactly the same as:

if x is not None: # do something

The former is a boolean value test and can evaluate to false in different contexts. There are a number of things that represent false in a boolean value tests for example empty containers, boolean values. None also evaluates to false in this situation but other things do too.

Tendayi Mawushe
+11  A: 

(ob1 is ob2) equal to (id(ob1) == id(ob2))

Mykola Kharechko
... but (ob is ob2) is a LOT faster. Timeit says "(a is b)" is 0.0365 usec per loop and "(id(a)==id(b))" is 0.153 usec per loop. 4.2x faster!
AKX
the `is` version needs no function call, and no python-interpreter attribute lookup at all; the interpreter can immediately answer if ob1 is, in fact, ob2.
kaizer.se
No, it does not. `{} is {}` is false and `id({}) == id({})` can be (and **is** in CPython) true. See http://stackoverflow.com/questions/3877230
Piotr Dobrogost
A: 

@Graeme Perrow , @Tendayi Mawushe: About translating the English statement "if x is None" to the Python code "if x is None:"... I did not understand why would you want to choose so..., apart to have a look-and-feel of programming with English statements... I would use instead "if x == None:" Python code, to check whether "x is None". Borrego's and Stephen's answers explain and elaborate on the purpose of "is". The fact that there's apparent no difference in these cases is not a good reason to rely on this quirk, for reasons such as implementations of Python that would not use caching of values would have broke your code, because this quirk depends on this detail. So if you are intending "x is None" write "x == None", as you would write "y is 10" as "y == 10". If still unclear please read: http://mail.python.org/pipermail/python-list/2001-November/113994.html Also there could be good reasons to write "x is None", but I cannot imagine any scenario that would make this useful. The point that "if" use implicit boolean conversions, with the effects mentioned, is correct, and is proper to be aware about it.

Dario Cangialosi
-1 `foo is None` does NOT depend on caching of values. `None` is a singleton by definition; it's neither a quirk nor an implementation detail. The link you give must be a mistake; its contents are absolutely irrelevant to the is/== discussion.
John Machin
+1  A: 

The reason foo is None is the preferred way is that you might be handling an object that defines its own __eq__, and that defines the object to be equal to None. So, always use foo is None if you need to see if it is infact None.

truppo