[Python-ideas] Multi Statement Lambdas
Chris Angelico
rosuav at gmail.com
Sun Oct 21 19:20:49 EDT 2018
On Mon, Oct 22, 2018 at 8:05 AM Vladimir Filipović <hemflit at gmail.com> wrote:
> From one popular library:
>
> ws = websocket.WebSocketApp(
> url,
> on_open = (lambda ws: ws.send('subscribe'); conn_counter += 1),
> on_message = (lambda ws, msg: print(msg); msg_counter += 1))
>
> Because they include statements, I again need to create those
> functions separately. Naming isn't so much a problem here, but it
> would turn kludgey if I needed to make several such calls in the same
> scope.
Cool! We have an example. Next step: Offer a variety of alternate
syntaxes that *do* currently work, and then the proposed
multi-statement lambda, and show how the current syntaxes are all
ugly.
One syntax that currently can be used to great effect is decorators. I
don't know the specific websocket library that you're using, but it's
generally not difficult to design something so that a function call
can do the assignment. It'd end up looking something like:
ws = websocket.WebSocketApp(url)
@ws.event
def on_open(sock):
sock.send('subscribe')
nonlocal conn_counter # or global, not sure
conn_counter += 1
@ws.event
def on_message(sock, msg):
print(msg)
nonlocal msg_counter
msg_counter += 1
Yes, it's a lot more vertical than your version. However, adding in
the nonlocal declarations definitely makes it look a LOT less
lambda-friendly.
This also takes a bit of extra support. But it can be third-party
support if you need it to. Worst case, you can make a little helper:
events = {}
def event(func):
events[func.__name__] = func
return func
@event
def on_open...
@event
def on_message...
ws = websocket.WebSocketApp(url, **events)
which will work with the same API. Great for larger and more complex setups.
ChrisA
More information about the Python-ideas
mailing list