In Python, bool(a.append(3)) is False. Why?
Question: It seems `bool(a.append)` and `bool(a)` are all `True`, but why
`bool(a.append(3))` is `False`?

My question is from the code here:

    
    
    class MovingAverage(object):
        def __init__(self, size):
            self.next = lambda v, q=collections.deque((), size): q.append(v) or 1.*sum(q)/len(q)
    


Answer: In Python, the following things are considered `False`. In other words, if you
call `bool` with them as arguments, you get `False` back:

  * `False` itself.
  * `0`, in integer or floating point form.
  * empty sequence types; strings, lists, sets, dictionaries, and anything that's a subclass of them
  * `None`

The last one is the most important to us here. The reason that
`bool(a_list.append(3))` is `False` has to do with how `append` works. The
`append` method updates the existing list. It doesn't return anything in
particular.

In Python, any function which does not explicitly return anything implicitly
returns the `None` value. That means that something like this won't work.

    
    
    my_list = []
    for i in range(10):
        if i % 2 == 0:
            my_list = my_list.append(i)
    

That code I just made up will actually throw an exception (`AttributeError`)
the second time the `if` block gets executed because `my_list` gets set to
`None`, and `None` doesn't have an `append` method, because it's not a list.

And just to be clear, _anything_ not on that list gets considered `True`. You
can change this for custom objects by overriding the `__bool__` special method
(it's called `__nonzero__` in Python 2).

So let's just finish up by clarifying why `bool(a.append)` is `True`. If you
leave the parentheses (and argument list) off a method call, the method
doesn't get called. So `bool(a.append)` is just passing the method `a.append`
to `bool` without calling it.

