Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing more arguments to this type of python function

I figure this is pretty basic, but can't seem to figure out even how to ask google the right question. I am using this python websocket client to make some websocket connections. Let's just assume I'm using the code example similar to that page:

import websocket
import thread
import time

def on_message(ws, message):
    print(message)

def on_error(ws, error):
    print(error)

def on_close(ws):
    print("### closed ###")

def on_open(ws):
    def run(*args):
        ws.send("Hello")
        time.sleep(1)
        ws.close()
        print("thread terminating...")
    thread.start_new_thread(run, ())


if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://echo.websocket.org/",
                              on_message = on_message,
                              on_error = on_error,
                              on_close = on_close)
    ws.on_open = on_open
    ws.run_forever()

So what I am trying to do is add more arguments to the on_open function, something like this:

def on_open(ws, more_arg):
    def run(*args):
        ws.send("Hello %s" % more_arg)
        time.sleep(1)
        ws.close()
        print("thread terminating...")
    thread.start_new_thread(run, ())

But i can't figure out how to pass these arguments in, so I tried in the main thread:

ws.on_open = on_open("this new arg")

But i get the error:

TypeError: on_open() takes exactly 2 arguments (1 given)

How am I going to pass these new arguments to my on_open function?

like image 913
jeffery_the_wind Avatar asked Dec 24 '22 15:12

jeffery_the_wind


2 Answers

Keep in mind that you need to assign a callback. You are instead calling a function and passing the return value to ws, which is incorrect.

You can use functools.partial to curry a function to a higher order one:

from functools import partial

func = partial(on_open, "this new arg")
ws.on_open = func

When func is invoked, it will invoke on_open with the first argument as "this new arg", followed by any other arguments passed to func. Look at the implementation of partial in the doclink for more details.

like image 171
cs95 Avatar answered Jan 06 '23 23:01

cs95


You can use a lambda to wrap the call:

ws.on_open = lambda *x: on_open("this new arg", *x)
like image 26
Netwave Avatar answered Jan 06 '23 23:01

Netwave