On Wed, Aug 12, 2015 at 09:57:03AM -0400, Scott Sanderson wrote:
Hi All,
Occasionally I find myself wanting to unpack the values of a dictionary into local variables of a function. This most often occurs when marshalling values to/from some serialization format.
I think that anything that is only needed "occasionally" doesn't have a strong claim to deserve syntax.
For example:
def do_stuff_from_json(json_dict): actual_dict = json.loads(json_dict) foo = actual_dict['foo'] bar = actual_dict['bar'] # Do stuff with foo and bar.
Seems reasonable and not too much of a burden to me. If I needed a lot of keys, I'd do: # sequence unpacking version spam, eggs, cheese, foo, bar, baz = [actual_dict[key] for key in "spam eggs cheese foo bar baz".split()]
In the same spirit as allowing argument unpacking into tuples or lists, what I'd really like to be able write is something like:
def do_stuff_from_json(json_dict): # Assigns variables in the **values** of the lefthand side by doing lookups # of the corresponding keys in the result of the righthand side expression. {'foo': foo, 'bar': bar} = json.loads(json_dict)
I think the sequence unpacking version above reads much better than this hypothetical dict unpacking version: {'foo': foo, 'bar': bar, 'baz': baz, 'spam': spam, 'eggs': eggs, 'cheese': cheese} = json.loads(json_dict) Both are roughly as verbose, both have a little duplication, but the sequence unpacking version requires far fewer quotation marks and other punctuation. I also think it's much more readable, and of course the big advantage of it is that it works right now, you don't have to wait two or three years to start using it in production. If there is a downside to the sequence unpacking version, it is that it requires a temporary variable actual_dict, but that's not a real problem. I don't think dict unpacking is needed when you have only two or three variables, and I don't think your suggested syntax is readable when you have many variables. So I would be -1 on this suggestion. However, if you wanted to think outside the box, it's a pity that locals() is not writable. If it were, we could do: locals().update(json.loads(json_dict)) although of course that might update too many local names. So, just throwing it out there for discussion: - Make locals() writable. If the compiler detects that locals() may be written to, that will have to disable the fast local variable access for that specific function. More practical, and in the spirit of tuple unpacking: spam, eggs, cheese = **expression being equivalent to: _tmp = expression spam = _tmp['spam'] eggs = _tmp['eggs'] cheese = _tmp['cheese'] del _tmp except that _tmp is never actually created/deleted. This is easier to write and simpler to read, and doesn't allow nested unpacking. (I consider that last point to be a positive feature, not a lack.) -- Steve