One of the annoying things about languages, specially dynamic languages, is some of the odd side effects. This is particularly challenging when trying to debug moderately complex or involved code fragments. Here an interesting code sample that I’m looking at right now:
3
4 def func(a, b, c={}):
5 if c:
6 print 'something is wrong'
7 d = a+b
8 c['a'] = a
9 c['b'] = b
10 c['d'] = d
11 return c
12
13
14 print func(1,2)
15 print func(1,2)
16
In the function declaration I set c with a default value {} which is an empty dict. And unless I provide the 3rd param I would expect c to be empty every time. However when I execute this function I get something different:
$ python bug.py
{'a': 1, 'b': 2, 'd': 3}
something is wrong
{'a': 1, 'b': 2, 'd': 3}
Notice that the message “something is wrong” is displayed. That means that the second call to func() is ignoring the emptyhash or it’s actually something completely different. The possible choices are: (1) {} defines a semi-static-scoped reference and not a new heap instance. (2) the ‘=’ assignment in the function prototype does not actually work as you would expect.
The lesson here might be more than is there a bug in the language design or implementation. More importantly it supports my A-1 best practice … stay in the sweet spot.







Eduardo Ferro Aldama (@eferro)
2012/04/07 at 16:51
Hi Richard….
You have a good explanation about the python evaluation of default parameters at http://effbot.org/zone/default-values.htm
Hope it helps…
Richard Bucker
2012/04/07 at 16:58
Thanks; the explanation is pretty good. And it’s interesting that the author says it happens only ONCE. So it’s probably not a bug but more of an unintentional side effect. (that’s just the pessimist in me.) Needless to say I do not like this behavior. For all the use-cases that support this behavior I can +1 the number where it does not.