A Python Gotcha: References as Default Parameters

Saturday, February 05, 2011.

Suppose you're writing a Python function like this one that unpacks data into a dictionary; optionally, an existing dictionary instead of an empty one.

Surprise!

$ python
Python 2.6.4
[GCC 4.4.1] on linux2
>>> def hashcopy(src, dst={}):
...   for k, v in src.items():
...     dst[k] = v
...   return dst
...
>>> hashcopy({1:2,3:4})
{1: 2, 3: 4}
>>> hashcopy({5:6,7:8})
{1: 2, 3: 4, 5: 6, 7: 8}

I haven't looked deeply into this, but it seems like default parameters must be bound to object instances at compile time.

In Perl 5 you typically only set default parameters at runtime, so the empty hashref you get is always the freshest in the land:

sub hashcopy
{
  my $src = shift;
  my $dst = shift || {};
  %$dst = (%$dst, %$src);
  return $dst;
}

All other things equal, this is undoubtedly slower, but considerably less wtf-subtle.

Posted by Alan on Saturday, February 05, 2011. (Discuss)

blog comments powered by Disqus
maelstrom

"After a little while I became possessed with the keenest curiosity about the whirl itself. I positively felt a wish to explore its depths, even at the sacrifice I was going to make; and my principal grief was that I should never be able to tell my old companions on shore about the mysteries I should see."

Illustration for Edgar Allan Poe's story "Descent into the Maelstrom" by Harry Clarke, published in 1919.