1

When checking a method's arguments to see whether they were set, is it pythonic to do an identity check:

def doThis(arg1, arg2=None):
  if arg2 is None:
    arg2 = myClass()

Or is it proper form to use a short-circuiting boolean:

def doThis(arg1, arg2=None):
    arg2 = arg2 or myClass()

In support of the former, PEP 8 states:

Comparisons to singletons like None should always be done with is or is not , never the equality operators. Also, beware of writing if x when you really mean if x is not None -- e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!

On the other hand, from the Google style guide:

Use the "implicit" false if at all possible. ...

But at the same time states...

Never use == or != to compare singletons like None. Use is or is not.

Does this apply to "None" since it evaluates to False always, and/or is a boolean comparison equivalent to ==/!= under the hood?

edit: To answer the last question, "or" doesn't seem to be equivalent to "==" under the hood:

In [17]: timeit.timeit("1 or None", number=100000000)
Out[17]: 2.0310521125793457

In [18]: timeit.timeit("1 is None", number=100000000)
Out[18]: 2.618263006210327

In [19]: timeit.timeit("1 == None", number=100000000)
Out[19]: 4.554893970489502
Ethereal
  • 2,604
  • 1
  • 20
  • 20

1 Answers1

4

Consider what would happen if arg2 equals a "Falsish" value such as zero (or an empty string, list, tuple, dict or set -- to name just a few). Then

arg2 = arg2 or myClass()

would set arg2 to myClass() even though arg2=0 might have been the intended value for arg2. So always use is to determine if arg2 is None.

Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677