268

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?

Mad Physicist
  • 95,415
  • 23
  • 151
  • 231
Clay Wardell
  • 13,546
  • 11
  • 41
  • 62
  • 7
    PEP 8 says somewhere that you should compare to singletons using `is` - http://www.python.org/dev/peps/pep-0008/#programming-recommendations – Volatility Jan 09 '13 at 22:11
  • 2
    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. – Clay Wardell Jan 09 '13 at 22:30
  • 2
    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. – I. J. Kennedy May 04 '14 at 21:47

6 Answers6

325

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
mgilson
  • 283,004
  • 58
  • 591
  • 667
  • Do you mean by overloading the == operator to always return True when compared to None? – Clay Wardell Jan 09 '13 at 22:08
  • 38
    When does `is None` differ from `== None`? – Blender Jan 09 '13 at 22:09
  • 19
    @Blender In the case mentioned. `__eq__` can be defined in any way, but the behavior of `is` can't be changed so easily. – Lev Levitsky Jan 09 '13 at 22:10
  • Ah, that last example with lst made it very clear. Thank you. – Clay Wardell Jan 09 '13 at 22:16
  • 8
    @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)." – abarnert Jan 09 '13 at 22:19
  • 1
    +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). – abarnert Jan 09 '13 at 22:20
  • 3
    @abarnert -- 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. – mgilson Jan 09 '13 at 22:24
  • @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. – John Strood Jan 04 '19 at 10:58
  • @mgilson 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. – John Strood Jan 04 '19 at 11:05
  • @mgilson So you see, idiomatically in Python `a is None` makes correct sense than `a == None`. – John Strood Jan 04 '19 at 11:05
  • @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. – Mad Physicist Apr 25 '20 at 18:15
  • -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. – exore Feb 09 '22 at 03:16
  • 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. – mgilson Feb 09 '22 at 13:38
163

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."

Chris
  • 6,647
  • 3
  • 53
  • 78
user4815162342
  • 124,516
  • 15
  • 228
  • 298
  • 12
    Thanks for posting this; the accepted answer makes some interesting points, but yours responds to the question much more directly. – Luke Davis Apr 26 '17 at 19:09
  • It seems weird to rely on what is essentially an implementation detail. Why should I care how many instances of NoneType there are? – BallpointBen Jan 17 '19 at 18:44
  • @BallpointBen 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.) – user4815162342 Jan 17 '19 at 18:48
  • 1
    @BallpointBen 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. – user4815162342 Jan 22 '19 at 13:24
  • `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. – user4815162342 Jan 22 '19 at 13:26
14

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

halfelf
  • 8,964
  • 13
  • 49
  • 61
Thorsten Kranz
  • 11,837
  • 1
  • 36
  • 53
6

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.

Danferno
  • 426
  • 4
  • 7
0

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()
-3

We can take the list for example. Look here:

a = list('Hello')
b = a
c = a[:]

All have the same value:

['H', 'e', 'l', 'l', 'o']
['H', 'e', 'l', 'l', 'o']
['H', 'e', 'l', 'l', 'o']

is refers to the actual memory slot, whether they are the specific object of interest:

print(a is b)
print(a is c)

Now we get the desired result.

True
False

PEP 8 also mentions this, saying "comparisons to singletons like None should always be done with is or is not, never the equality operators."

is is also faster.

Aarav Dave
  • 79
  • 1
  • 7
  • I think the PEP8 quote is the right answer, maybe worth presenting just that. I don't get the point of your example. – BobHy May 18 '21 at 20:19
  • The asker said 'if so, and why', so here's why, to avoid errors. PEP8 is a side thing and a formatting guide. But I did put it anyways, so others can refer. – Aarav Dave May 19 '21 at 16:44
  • But your example is incorrect. The expression `print( None is print())` displays `True` (on my copy of Python 3.8.6). I'd say the answer to the question of "if so, why" is just that PEP8 recommends this idiom, and the asker's editor enforces that recommendation. – BobHy May 20 '21 at 20:41
  • Oh yes, sorry. It would be `None is print`. I will fix that right away. – Aarav Dave May 22 '21 at 00:55
  • @AaravDave I will not downvote you, but your correction is also wrong. `None is print()` gives a true value because `print` doesn't return anything. So you are checking if the return of `print()` is `None`, which it is. `None is print` gives a false value because now you are checking if the function `print` is the `None` object. These things have nothing to do with one another. – giusti Apr 08 '22 at 21:04
  • This was quite a long time ago, but if we were to put the values in two seperate variables and change it as such then it will be different. Is refers to the RAM memory slot and if those are not the same then the is function returns false. I was a young programmer then! – Aarav Dave Apr 09 '22 at 22:22