[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