📑

Pythonでdebounce

2023/04/02に公開

Pythonでdebounceを実現するサンプルコードです。
このサンプルコードでは、最後のユーザ入力から2秒間入力がない場合に最後の入力をメッセージとして出力する仕組みになっています。

Python 3.10.10 で動作確認済みです。

サンプルコードについて補足説明しますと、
nonlocalを使用することで、
関数の外側の変数(例. timer, callback, waittime)にアクセスしています。
また、debouncerは「引数として与えた関数callbackをwaittime秒だけdebounceした関数を返す」関数で、
以下サイトのJavaScriptの実装をほぼそのままPythonで実装しました。
https://www.webdesignleaves.com/pr/jquery/debounce-and-throttle.html

import threading
from typing import Any, Callable


class SayHelloMachine:
    def __init__(self, name: str) -> None:
        self.name = name
        self.debounced_hello = debouncer(self._say_hello, 2)

    def _say_hello(self, message: str):
        print("")
        print(f"Hello, {self.name}. {message}")
        print(">> ", end="", flush=True)

    def say_hello(self, message: str):
        self.debounced_hello(message)


def debouncer(callback: Callable[..., Any], waittime: int = 1) -> Callable[..., Any]:
    timer: threading.Timer | None = None

    def debounced_callback(*args):
        # print(f"debounced_callback called. args={args}")
        nonlocal timer
        nonlocal callback
        nonlocal waittime

        if timer is not None:
            timer.cancel()
        timer = threading.Timer(
            waittime,
            callback,
            args
        )
        timer.start()

    return debounced_callback


if __name__ == "__main__":
    hello_machine = SayHelloMachine("Mike")
    i = 1
    while True:
        message = input('>> ')
        hello_machine.say_hello(f"message[{i}]: {message}")
        i = i + 1

Discussion