identity versus equality for None in Python

Various Python guides say to use x is None instead of x == None. Why is that? Equality is used for comparing values, so it seems natural to ask if x has the value None, denoted with == and not is. Can someone explain why is is the preferred form and show an example where the two do not give the same answer?

Thanks.


Solution 1:

The reason people use is is because there is no advantage to using ==. It is possible to write objects that compare equal to None, but it is uncommon.

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

print A() == None

Output:

True

The is operator is also faster, but I don't consider this fact important.

Solution 2:

The is keyword tests identity. It is not a comparison operator like ==. Using is does more than test whether two arguments have the same value and/or the same internal structure: namely, it tests whether the two actually refer to the same object in memory. There are numerous implications to this, one of them being that is cannot be overloaded, and another being that behavior differs between mutable and immutable types. For example, consider the following:

>>> l1 = range(5)
>>> l2 = range(5)
>>> l1 == l2
True
>>> l1 is l2
False
>>> l3 = l1
>>> l1 is l3
True
>>> s1 = "abcde"
>>> s2 = "abcde"
>>> s1 == s2
True
>>> s1 is s2
True

Here, because lists are mutable, they cannot share a location in memory, and consequently is and == yield discrepant results. On the other hand, strings are immutable, and therefore their memory may be pooled in some cases. Basically, is can only reliably be used for simple, immutable types, or in instances when multiple names point to exactly the same object in memory (such as the use of l3 in the above example), and its use indicates a desire to test identity rather than value. I would expect is to be slightly faster than == because it doesn't perform method lookup, but I could be mistaken. Of course, for complex container objects like lists or dicts, is should be much faster than == (O(1) vs. O(n), presumably). That said, the speed issue is mostly a moot point, as the two should not be regarded as interchangeable.

Solution 3:

PEP 8 says: "Comparisons to singletons like None should always be done with 'is' or 'is not', never the equality operators." Here is a quite good explanation why:

http://jaredgrubb.blogspot.com/2009/04/python-is-none-vs-none.html