In the past few months I’ve been helping some people who are new to Python to get to know the language. I found that there are some pitfalls that almost everyone meet when they’re new to the language, so I decided to share my advice with you. Each part of this series will focus on a different common mistake, describe what causes it and offer a solution.
This is a companion discussion topic for the original entry at http://amir.rachum.com/blog/2013/07/06/python-common-newbie-mistakes-part-1/
For conciseness, these are equivalent:
if numbers is None:
numbers = 
numbers = numbers or 
They are not quite equivalent. The first explicitly checks the identity of numbers; the second checks its truthiness. The difference often matters: for example, using a logical or in the second definition of foo() would mutate the list supplied only if it was not empty.
I would call this a wart in Python's design. Amir addressed this point somewhat. For mutable values, each call of a function should get a copy of the default value. One possible counterpoint is that in some way the existing semantic could be useful, but I think that's a weak argument. I don't see any use for this behavior that can't be addressed MUCH more clearly with a closure, an instance variable or a class variable.
Good article. I've just tried your examples in Scala and everything works as expected. My observation is that Scala really helps you to avoid bugs.
Just a suggestion... Lose the "Uh... Privilege" line. This blog is attracting novice python coders and it makes you sound like a condescending prick.
It's all in good humor, but I accept your criticism and I'll change it.
Here (using pythontutor) we can see what's happen in a visual mode:
Wow, this tool is amazing!
if numbers is None: could be better done as:
numbers = numbers if numbers else 
Then the most pythonic way would be to do:
numbers = numbers if numbers is not None else 
Thanks! You know, I was having stranger bug for my first python project. And then I find this article. You are saving my Saturday!