if A vs if A is not None:
Solution 1:
The statement
if A:
will call A.__bool__()
(see Special method names documentation), which was called __nonzero__
in Python 2, and use the return value of that function. Here's the summary:
object.__bool__(self)
Called to implement truth value testing and the built-in operation
bool()
; should returnFalse
orTrue
. When this method is not defined,__len__()
is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither__len__()
nor__bool__()
, all its instances are considered true.
On the other hand,
if A is not None:
compares only the reference A
with None
to see whether it is the same or not.
Solution 2:
As written in PEP8:
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!
Solution 3:
if x: #x is treated True except for all empty data types [],{},(),'',0 False, and None
so it is not same as
if x is not None # which works only on None
Solution 4:
A lot of functions return None if there are no appropriate results. For example, an SQLAlchemy query's .first()
method returns None if there were no rows in the result. Suppose you were selecting a value that might return 0 and need to know whether it's actually 0 or whether the query had no results at all.
A common idiom is to give a function or method's optional argument the default value of None, and then to test that value being None to see if it was specified. For example:
def spam(eggs=None):
if eggs is None:
eggs = retrievefromconfigfile()
compare that to:
def spam(eggs=None):
if not eggs:
eggs = retrievefromconfigfile()
In the latter, what happens if you call spam(0)
or spam([])
? The function would (incorrectly) detect that you hadn't passed in a value for eggs
and would compute a default value for you. That's probably not what you want.
Or imagine a method like "return the list of transactions for a given account". If the account does not exist, it might return None. This is different than returning an empty list (which would mean "this account exists but has not recorded transactions).
Finally, back to database stuff. There's a big difference between NULL and an empty string. An empty string typically says "there's a value here, and that value is nothing at all". NULL says "this value hasn't been entered."
In each of those cases, you'd want to use if A is None
. You're checking for a specific value - None - not just "any value that happens to cast to False".