将附加参数传递给只需要 1

问题描述

所以我正在做一个小项目,我正在使用 websocket 客户端库,为了创建一个处理 websocket 连接的 WebSocketApp 对象,你使用类似的东西实例化该对象

ws = websocket.WebSocketApp(uri,on_open=on_open,on_message=on_message,on_ping=on_ping)

现在我有一个名为 on_message函数,它是处理传入消息的回调函数(对象?),或者更确切地说是如何处理它们,并由 ws 对象调用我创建,当一条完整的消息进来时(显然)。 on_message 定义为实例化 WebSocketApp 对象时的回调。

on_message 是这样的

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

我想要的是这样的:

def on_message(ws,message,someList)
    somelist.append(message)

我当然可以使用全局变量来引用我想要更新的对象(在本例中是一个列表),但这似乎不是正确的方法,如果我可以传递引用就好了到我想在初始化 WebSocketApp 对象时更新的对象,例如:

ws = websock.WebSocketApp(uri,on_message=on_message(ref_to_Obj),on_close=on_close)

但显然这不起作用,因为我收到了 TypeError: on_message() missing 2 required positional arguments: 'message' and objRef' 错误

我不完全确定如何解决这个问题。我想到了子类化,但不确定我将如何以这种方式完成它。查看 WebSocketApp 的来源,它说它有 2 个参数,1) WebSocketApp 类本身和 2) 从服务器接收的 utf-8 数据。我从不传递这些,我假设库在创建它们时只是将这些引用传递出去,但是我如何重载它以包含其他参数?首先想到的是使用 *args 或 **kwargs 重载,但又不确定如何实现。我之前问过,建议使用 lambda 函数,但我也不知道如何让它工作。

解决方法

您想要 "partially apply" 函数。这可以使用 partial:

完成
from functools import partial

ws = websock.WebSocketApp(uri,on_message=partial(on_message,someList=ref_to_Obj))

partial 接受一个函数和参数(我在这里使用关键字参数),并返回一个 new 函数,该函数已经传递了部分应用的信息。

“穷人的”版本将只使用 lambda

ws = websock.WebSocketApp(uri,on_message=lambda ws,msg: on_message(ws,msg,ref_to_Obj))

partial 应该是首选,因为它维护来自原始函数的元数据,这很有用。