Python None comparison: should I use "is" or ==?
Asked Answered
A

6

310

My editor warns me when I compare my_var == None, but no warning when I use my_var is None.

I did a test in the Python shell and determined both are valid syntax, but my editor seems to be saying that my_var is None is preferred.

Is this the case, and if so, why?

Arrowroot answered 9/1, 2013 at 22:6 Comment(4)
PEP 8 says somewhere that you should compare to singletons using is - python.org/dev/peps/pep-0008/#programming-recommendationsParalyse
That poster is talking about Python 3, and my question is about Python 2.x. I am not sure if this is a big enough difference to warrant both remaining but I edited the question to include that just in case.Arrowroot
I don't think this question is really a duplicate. The other was about == vs is in general, this one is about None in particular.Contractive
I've downvoted every answer because none of them gives a convincing reason, nor does PEP8. It says "Comparisons to singletons like None should always be done with is or is not, never the equality operators." Are True and False "singletons like None"? Apparently, so I guess I should say "if x is True"? Are ints between -5 and 256 "singletons like None"? Apparently (see @doublefelix 's answer), so I guess I should say "if x is -5" but "if x == -6"? This seems like nonsense; why on earth would I want to memorize any of this? As far as I can see, == works perfectly well for all of these.Compensable
A
356

Summary:

Use is when you want to check against an object's identity (e.g. checking to see if var is None). Use == when you want to check equality (e.g. Is var equal to 3?).

Explanation:

You can have custom classes where my_var == None will return True

e.g:

class Negator(object):
    def __eq__(self,other):
        return not other

thing = Negator()
print thing == None    #True
print thing is None    #False

is checks for object identity. There is only 1 object None, so when you do my_var is None, you're checking whether they actually are the same object (not just equivalent objects)

In other words, == is a check for equivalence (which is defined from object to object) whereas is checks for object identity:

lst = [1,2,3]
lst == lst[:]  # This is True since the lists are "equivalent"
lst is lst[:]  # This is False since they're actually different objects
Accomplished answered 9/1, 2013 at 22:8 Comment(13)
Do you mean by overloading the == operator to always return True when compared to None?Arrowroot
When does is None differ from == None?Conscience
@Conscience In the case mentioned. __eq__ can be defined in any way, but the behavior of is can't be changed so easily.Horsehair
Ah, that last example with lst made it very clear. Thank you.Arrowroot
@LevLevitsky: One of the example uses of Mython was "extending the protocols so any operator can be overloaded, even is". After a comment on the lists, he changed that to, "… even is (but only if you're insane)."Lammond
+1, but it would be even better if this answer included the PEP 8 reference that the others do (as well as explaining why the decision behind PEP 8 makes sense, which it already does).Lammond
@Lammond -- I wasn't even aware that PEP 8 made a recommendation here. The point is that they're different operators that do different things. There might be cases where object == None actually is the correct idiom (though I can't think of any off the top of my head). You just need to know what you're doing.Accomplished
@LevLevitsky I always use a mnemonic to remember that "is compares address while == compares value". I haven't gone wrong any day using this mnemonic. Going by that, changing the implementation of is is like faking another address.Metralgia
@Accomplished If you go by other languages, or Java for instance, a == null means the value (or pointer value) of a is really just a special literal called null, which is neither an instance nor value comparable to anything. Python lacks that, and the None is a singleton instance of the NoneType class. a == None would just be crazy because I could override __eq__ and make it equal to None every time even when it isn't. Meanwhile a is None is simply try to equate the address of a singleton object that is supposed to represent all null objects in the world.Metralgia
@Accomplished So you see, idiomatically in Python a is None makes correct sense than a == None.Metralgia
@JohnStrood Python's id(a) == id(None) is equivalent both to a is None and Java's a == null. This does not have anything to do with absolute correctness. I'm most cases you will want to use is. That in no way means that there aren't cases where == makes more conceptual sense. Not being able to think of one is merely a failure of imagination, not a rule of the universe.Washing
-1 because the question is not answered. The question is "should I use....". But what is the answer ? a long "this is how it works", while it should be "you should ....". In the end the primary question is not even answered. The second question "Is 'myvar is None' prefered and if so why", has no answer either.Mandamandaean
Hrmm ... Not sure I understand. I think the first sentence answers the question: Use "is" when you want to check against an object's identity (e.g. checking to see if var is None). I state the guiding principle and then the example is a direct answer to OP's question.Accomplished
A
191

is is generally preferred when comparing arbitrary objects to singletons like None because it is faster and more predictable. is always compares by object identity, whereas what == will do depends on the exact type of the operands and even on their ordering.

This recommendation is supported by PEP 8, which explicitly states that "comparisons to singletons like None should always be done with is or is not, never the equality operators."

Ashe answered 9/1, 2013 at 22:10 Comment(5)
Thanks for posting this; the accepted answer makes some interesting points, but yours responds to the question much more directly.Amir
It seems weird to rely on what is essentially an implementation detail. Why should I care how many instances of NoneType there are?Hymnody
@Hymnody Because it's not an implementation detail - there is only one None object under the global constant None. If anything, the NoneType is an implementation detail because the None singleton must have some type. (The fact that you cannot create instances of this type is a good indication that its one instance is intended to be a singleton.)Ashe
@Hymnody I think the key point is that Python possesses a strong concept of object identity. If you want to check whether an object compares equal to None, by all means use obj == None. If you want to check whether an object is None, use obj is None. The point of the PEP 8 recommendation (and of this answer) is that most people want the latter when they want to check for None, and it also happens to be faster and clearer.Ashe
None is also different than cached objects like 0 and other small integers, where the caching really is an implementation detail. The difference there is that an integer has intrinsic value which gives its properties and it can be calculated. On the other hand, None has no state whatsoever, it's only its identity that matters and makes it special.Ashe
T
12

PEP 8 defines that it is better to use the is operator when comparing singletons.

Territus answered 9/1, 2013 at 22:11 Comment(2)
I don't see anywhere where PEP8 justifies this recommendation. Do you have a link?Milda
@BT peps.python.org/pep-0008/#programming-recommendationsUnmannered
B
5

I recently encountered where this can go wrong.

import numpy as np
nparray = np.arange(4)

# Works
def foo_is(x=None):
    if x is not None:
        print(x[1])

foo_is()
foo_is(nparray)

# Code below raises 
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
def foo_eq(x=None):
    if x != None:
        print(x[1])

foo_eq()
foo_eq(nparray)

I created a function that optionally takes a numpy array as argument and changes if it is included. If I test for its inclusion using inequality operators !=, this raises a ValueError (see code above). If I use is not none, the code works correctly.

Bary answered 9/4, 2021 at 14:15 Comment(2)
Based on the error you're getting.. this has nothing to do with None. It has to do with the fact that you're comparing an array to none. Its the array causing your problem, not None.Milda
I'm not sure what you are trying to say? That's the whole point? That if you just want to check whether it is (exactly) None, it will always work out with is even if the provided value is of a completely different type (e.g. an array). Whereas the equality operators are only defined for the same type.Bary
S
2

A useful tidbit to add to people's understanding.

The reason that we check for identity with None is because Python only ever stores the value None in one place in memory, and every object which equals None has its value stored in this same location. There are a handful of "special values" which get this treatment, and None is just one of them.

But most values do not get this special treatment! For example, the float 1.25 can be stored in different locations in memory:

a = None
b = None
a is b

True

a = 1.25
b = 1.25
a is b

False

It just so happens that None is among the handful of values which are always stored in one place in memory. Another example is any integer between -5 and 256... since these integers are used often, they are always stored in memory, and every integer with that value is stored in the same place in your computer's memory! Try it out:

a = 256
b = 256
a is b

True

a = 257
b = 257
a is b

False

So you can think of None as being part of a special class of values which always have a constant memory address. That is why we can use is to check whether two variables are both None... it just checks whether the memory address is the same.

Edit: Joooeey makes the good point that which integers are stored in memory is specific to your python implementation, and the example of numbers from -5 to 256 is specific to CPython. If you don't know what you're running, it's probably CPython, which is the most common implementation. But for this reason (and others) it is better practice to compare equality between these numbers with a == 2 and not with a is 2. As for None, it is specified to be the sole instance of the NoneType type according to the Python Documentation itself, so regardless of implementation you can always compare it using a is None.

Scatter answered 3/8, 2022 at 13:12 Comment(1)
The examples about floats and integers apply specifically to the CPython implementation of Python. None however is defined as a singleton in the Python language spec: docs.python.org/3/library/constants.html#NoneGuizot
O
-2

Another instance where "==" differs from "is". When you pull information from a database and check if a value exists, the result will be either a value or None.

Look at the if and else below. Only "is" works when the database returns "None". If you put == instead, the if statement won't work, it will go straight to else, even though the result is "None". Hopefully, I am making myself clear.

conn = sqlite3.connect('test.db')
c = conn.cursor()
row = itemID_box.get()

# pull data to be logged so that the deletion is recorded
query = "SELECT itemID, item, description FROM items WHERE itemID LIKE '%" + row + "%'"
c.execute(query)
result = c.fetchone()

if result is None:
    # log the deletion in the app.log file
    logging = logger('Error')
    logging.info(f'The deletion of {row} failed.')
    messagebox.showwarning("Warning", "The record number is invalid")
else:
    # execute the deletion
    c.execute("DELETE from items WHERE itemID = " + row)
    itemID_box.delete(0, tk.END)
    messagebox.showinfo("Warning", "The record has been deleted")
    conn.commit()
    conn.close()
Ontario answered 26/6, 2021 at 23:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.