0

I've used python2 for years without even knowing about this feature, but apparently tuple unpacking is supported in function defs:

>>> def foo(a, (b, c)):
...     print a, b, c
...     
>>> t = (2, 3)
>>> foo(1, t)
1 2 3

Defaults are also allowed, though they seem to be unpacked at function call time and not function def time. And I couldn't figure out how to pass one/any/all of the packed arguments by name, maybe it's impossible.

>>> def foo(a, ((b, c), d)=('xy', 8)):
        print a, b, c, d
...     
>>> foo(0)
0 x y 8

This is not apparently not just a weird implementation detail: if you read the grammar carefully, in particular what an fpdef is, you see that function definitions are explicitly designed for tuple unpacking.

My question is, why was this a design choice and what is an example use-case where it's necessary? To me it seems an obscure and error-prone feature that violates zen of python 1, 2, 3, 5, 7, 9, 13, 17....

wim
  • 338,267
  • 99
  • 616
  • 750

1 Answers1

3

The feature was put in as a natural generalization of the unpacking you can do in ordinary variable assignments. The feature is completely unnecessary. It was removed in Python 3 because it didn't add much and made introspection messy.

Parameters like these cannot be passed by name. The tuple parameter is given an internal name like .0, and the bytecode of the function starts out by unpacking any tuple parameters. While it's technically possible to do something like

>>> def f((a, b)):
...     print a, b
...
>>> f(**{'.0': (0, 1)})
0 1

, it's not really useful.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • Thanks Kevin. That PEP was exactly what I was looking for. – wim Mar 31 '16 at 00:02
  • One consequence of this PEP is that `sorted(seq, key=lambda (a,b): a*b)`, which used to work in Python 2.7, is now a syntax error in Python 3. – wim Mar 20 '17 at 19:43