用Python实现任意无限递归

2024-04-26 07:22:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用Python(3.7)开发麦克风监听器。你知道吗

为了处理音频流,我编写了一个在线程上运行的函数,并在最后调用它自己(尾部递归)

class Listener:
    # [...]

    def __init__(self, audio_conf: AudioConfiguration, listener_callback: Callable[[bytes], None] = None) -> None:
        self.__configuration = audio_conf
        if listener_callback:
            self.__listener_callback = listener_callback
        self.__stream = PyAudio().open(format=self.__configuration.FORMAT,  # p.get_format_from_width(WIDTH),
                                       channels=self.__configuration.CHANNELS,
                                       rate=self.__configuration.RATE,
                                       input=True,
                                       output=True,
                                       frames_per_buffer=self.__configuration.CHUNK)
        thread = Thread(target=self.__listen, args=())
        thread.start()

    # [...]
    def __listen(self) -> None:
        if self.__flag_deactivation:
            if self.__listener_callback:
                print(f"Call listener callback")
                p = Process(target=self.__listener_callback, args=(self.__active_buffer,))
                p.start()
                # p.join()
            self.reset_state()
        tmp_buffer: bytes = b""
        count: int = 0
        voice: int = 0
        for i in range(0, self.__configuration.FRAMES_LENGTH):
            tmp_buffer += self.__stream.read(self.__configuration.CHUNK_SIZE)  # read audio stream
            count += 1
            if self.__mic_tuning.is_voice():
                voice += 1
        self.__previous_buffer = tmp_buffer
        if self.__active:
            self.__active_buffer += tmp_buffer
        print(f"Listening {'active' if self.__active else 'background'} - Voice Threshold {voice / count}")
        self.__listen()

显然,Python抱怨“最大递归深度”。。。你知道吗

有没有办法:

  • 去掉最大递归深度(但我认为这不是一个好主意,它可以隐藏一些其他问题…

  • 或者重写它而不使用尾部递归(但要保持效率)

我已经很久没有使用Python了,所以我很乐意学习一些“pythonic”的方法来实现这一点,而不必攻击默认行为:)

谢谢!你知道吗


Tags: selfnonestreamifbuffercountcallbackaudio