A real, if silly problem:
https://github.com/joshmarshall/tornadorpc/blob/master/tornadorpc/base.py
def start_server(handlers, ...):...for (route, handler) in handlers:...
Normally "handlers" is a list of 2-element tuples. But with this particular solution (Tornado) you can pass a third argument to a particular handler (kw args). So a tuple in "handlers" may have 2 elems sometimes or 3 elems other times.
I need to unpack this in a loop. Sure, I can do smth like length checking or try..except on unpacking. Ugh.
Can you think of smth better/more clever than this:
In [8]: handlers
Out[8]: [(1, 2), (3, 4, 5), (6, 7)]In [9]: new_handlers = [x + (None,) for x in handlers]
?
If that handler takes keyword arguments, then use a dictionary for the third element:
handlers = [(1, 2, {}), (3, 4, {'keyword': 5), (6, 7, {})]for route, handler, kwargs in handlers:some_method(route, handler, **kwargs)
Or you can apply the arguments using *args
syntax; in that case just catch all values in the loop:
for args in handlers:some_method(*args)
If you have to unpack into at least 2 arguments, do so in a separate step:
for handler in handlers:route, handler, args = (handler[0], handler[1], handler[2:])
where args
would be a tuple of 0 or more elements.
In Python 3, you can handle arbitrary width unpacking with a splat (*
) target:
for route, handlers, *args in handlers:
where *args
captures 0 or more extra values in the unpack.
The other route, to elements in handlers
to a minimal length could be done with:
[(h + (None,) * 3)[:3] for h in handlers]
Demo:
>>> handlers = [(1, 2), (3, 4, 5), (6, 7)]
>>> [(h + (None,) * 3)[:3] for h in handlers]
[(1, 2, None), (3, 4, 5), (6, 7, None)]