Python's extra-clever function parameters

February 27, 2006

I'm not sure where I ran across this, but until recently I wasn't aware that you could pre-explode lists and tuples when you declared what parameters a function takes. That sounds stilted, so I'll give an example:

def foo(a, (b, c, d)):
  print a, b, c, d

This is slightly more compact than the equivalent:

def bar(a, tmp):
  b, c, d = tmp
  print a, b, c, d

Contrary to what it might first look like, foo's second argument doesn't have to be an explicit list or tuple with three elements. Instead, it can be anything that will yield exactly three values when iterated. Want to pass xrange(0, 3), or even {1: 10, 2: 20, 3: 30}? No problem.

(Iterating a dictionary returns the keys (in some random order, so this is not necessarily a useful example).)

This freedom comes with a small drawback. Compare:

>>> foo(10)
TypeError: foo() takes exactly 2 arguments (1 given)
>>> foo(10, (1, 2))
ValueError: unpack tuple of wrong size

(I have elided the tracebacks.)

This is different from a language like Haskell, which has a more pattern-matching approach to this; I believe in Haskell you would get an 'argument mismatch' type of error in both cases. (Haskell looks like the kind of mind-bending neat language that's worth reading about, even if you never write a Haskell program.)

Writing this made me curious enough to look at the actual bytecodes generated for foo and bar (with the dis module). It turns out that they're pretty much identical, because foo starts with a prequel bit to explicitly unpack an explicit but internal second argument into b, c, and d. So foo is pretty much just syntactic sugar, supported by the bytecode compiler, for what bar writes out explicitly.

Although I've used this in code recently, I'm not sure it's entirely a good idea. Sometimes I feel that Python is a little bit too clever for my own good, and that I would be better off if I could resist the temptation to use some of these neat features.

(PS: yes, you can nest pre-exploded parameters. Don't go there.)

Written on 27 February 2006.
« Weekly spam summary on February 25th, 2006
A surprising effect of RAID-1 resynchronization »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Mon Feb 27 03:12:59 2006
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.