【问题标题】:Passing additional arguments to a callback object that only takes 1将附加参数传递给只需要 1 的回调对象
【发布时间】:2021-09-20 04:56:29
【问题描述】:

所以我正在做一个小项目,我正在使用 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_open=on_open, 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 函数,但我也不知道如何让它工作。

【问题讨论】:

标签: python-3.x arguments parameter-passing overloading keyword-argument


【解决方案1】:

你想"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 应该是首选,因为它维护来自原始函数的元数据,这可能很有用。

【讨论】:

  • 非常感谢您的帮助!!看看无论我做什么,我都无法让 lambda 版本工作,由于某种原因它仍然给我带来了问题。
  • 所以执行此操作的 lambda 方式似乎不起作用,它永远不会进入函数。我现在要试试 functools 方法。
  • @user1884295 两种方式几乎相同,不应导致您所描述的情况。它们的行为应该与以前完全相同,只是结束了一个额外的参数。我会先检查连接问题。
  • 没关系,我偏爱工作,但 lambda 给我带来了问题,所以感谢您的帮助!
  • @user1884295 出于好奇,有什么问题?就像我说的,它们的性能应该相同。
猜你喜欢
  • 2014-06-14
  • 2012-03-23
  • 2017-11-10
  • 2011-06-29
  • 1970-01-01
  • 1970-01-01
  • 2019-08-09
  • 2016-09-19
  • 1970-01-01
相关资源
最近更新 更多