将参数传递给回调

问题描述

键盘模块上的add_word_listener有点麻烦。如果我有一个接受回调作为参数的函数,如何将参数传递给回调?例如,这是最小的可复制代码

import keyboard

stopKey = "Windows"


def test(arg):
    print(arg)

keyboard.add_word_listener("hi",test("Hello World!"))

running = True
while running:
    if keyboard.is_pressed(stopKey):
        running = False

add_word_listener一个具有2个必需参数,其侦听文本和回调的函数。在键盘文档页面上,回调参数被描述为“每次键入单词时都会调用的无参数函数”。那么这是否意味着我无法将参数传递给test中的add_word_listener函数?该代码仅在我们删除参数并仅具有keyboard.add_word_listener(“ hi”,test)时有效。如果这是唯一的方法,是否有更好的方法在此处传递带有参数的函数,而不是创建许多特定的函数?即不要创建类似

函数
def printhi():
    print("hi")
    
def printhello():
    print("hello")

每次我想使用add_word_listener吗?

解决方法

martineau 提到了lambda作为解决方案

keyboard.add_word_listener("hi",lambda: test("Hello World!"))

另一个是functools.partial

keyboard.add_word_listener("hi",functools.partial(test,"Hello World!"))

您甚至可以使用__call__方法而非函数来创建类

class Test:
    def __init__(self,arg):
        self.arg = arg
    def __call__(self):
        print(self.arg)

keyboard.add_word_listener("hi",Test("Hello World!"))

如果您想保留一些额外状态,那么最后一个很有用。就像一个虚构的示例一样,如果您想记录何时进行回调,则可以

class Test:
    def __init__(self,arg):
        self.arg = arg
    def __call__(self):
        self.called_at = time.time()
        print(self.arg)

test = Test("Hello world")
keyboard.add_word_listener("hi",test)
,

我喜欢以上两种解决方案。如果lambda吓到了您,您还可以使用其他功能。

def my_callback():
    test("hello")

keyboard.add_word_listener("hi",my_callback)

您甚至可以像这样编写更多通用代码:

def add_my_word_listener(word,callback_word):
    def my_callback():
        test(callback_word)
    keyboard.add_word_listener(word,my_callback)

add_my_word_listener("hi","hello")
add_my_word_listener("ciao","goodbye")