Python's Mutable Default Problem 201
Today I was perusing a very fine python article all professional python programmers should read. I had to grin when I saw one of my favorite python quirks/flaws.
Python only evaluates default parameters when it defines a function, leading to surprising side effects (example from saifoo):def function(item, stuff = []): stuff.append(item) print stuff function(1) # prints '[1]' function(2) # prints '[1,2]' !!!
The grin on my face was because I was bit by this one again last Tuesday. You just don’t want to make a mutable object a default parameter. The solution I used was close to the solution from saifoo:
Saifoo.net:def function(item, stuff=None): if stuff is None: stuff = [] stuff.append(item) print stuffThis, of course, gives the correct behavior because it creates a new empty list each time it is called without a second parameter.
My solution actually combines some advice contained earlier in the article with the solution given for this problem:
Minedef function(item, stuff=None): stuff = stuff or [] stuff.append(item) print stuff
It’s not necessarily prettier, and I struggle with whether it is more obvious (to a Python programmer) or not. I fear it may be clever (a word I only use in the pejorative sense), but it is also clean-looking to me.
The point remains, though, that the mutable default parameter quirk is an ugly corner worth avoiding, and I suspect that any code that purposefully exploits that behavior to populate a structure that persists across calls will run a very real risk of being misunderstood.
We all know what happens when the next programmer to touch a program misunderstands it.