In python, why is 'is' preferred over '==' for checking if an object is in None

If I write this:

if x == None:
    x = 1

      

My pyCharm editor keeps suggesting that I should be using 'is' instead of '==':

if x is None:
    x = 1

      

For any other equality check pyCharm does not assume the use of 'is', e.g .:

if x == 2:
    x = 1

      

Why does the operator 'is'

prefer the operator '=='

when checking if there is an object None

?

Why is it preferred only for None

?

+3


source to share


1 answer


Because it None

is singleton, there is only one copy of the object in a Python program .

is

faster when testing on a single object, because only pointers need to be equal. ==

tests for more information, the state of the tested objects should be the same in this case.

This becomes more pronounced if your object x

implements its own method object.__eq__()

; it will be called every time you use x == None

, and x is None

does not have such a hook. This means that the interpreter must execute another Python code every time you run an equality test. Did I mention that a simple pointer equality test (used for is

) is fast?

This hook also allows you to declare yourself a non-standard type None

:

class Devious(object):
    def __eq__(self, other):
        return other is None

      

Now your test x == None

will be true, although x

not really None

, but an instance Devious

. If you really wanted to know if it was x

installed on None

, only x is None

be able to detect this case.



None

is not the only object with which you can verify identification. Any time you need to know if a given name refers to a specific object and not a value, you should use is

.

For example, sometimes you need to allow to None

be a valid value, but you want to determine if a value is not specified. You can usually use it None

as a checker to determine if an argument is left:

def foo(arg1, optional=None):
    if optional is None:
        # no value given for optional

      

but if you wanted to None

be a valid value, you would use a different watch:

_sentinel = object()

def foo(arg1, optional=_sentinel):
    if optional is _sentinel:
        # no value given for optional

      

You can now use foo(1, None)

it and it will correctly be treated as a value.

+8


source







All Articles