Python中Google语音识别失败回调chunks_process后for循环重复执行问题求解
问题根因
你的代码存在两个核心问题导致重复执行:
- 递归调用
chunks_process处理完从i到末尾的所有分片后,当前层的for循环没有终止,会继续从i+1遍历后续已经被递归处理过的分片,产生重复执行 - Python中字符串是不可变类型,递归内部对
whole_text的修改不会同步到外层函数,最终拼接结果会丢失递归处理的内容 - 额外风险:裸
except会捕获所有异常包括键盘中断等非接口错误,且没有重试次数限制,极端情况会触发栈溢出
最优修复方案(非递归重试)
直接在当前循环内对识别失败的分片做有限次重试,逻辑更清晰无重复执行风险:
import os import speech_recognition as sr def chunks_process(chunks, folder_name, max_retry=3): r = sr.Recognizer() whole_text = "" for i in range(len(chunks)): chunk_filename = os.path.join(folder_name, f"chunk{i}.wav") chunks[i].export(chunk_filename, format="wav") with sr.AudioFile(chunk_filename) as source: audio_listened = r.record(source) # 单分片内重试最多max_retry次 text = None for retry_cnt in range(max_retry): try: text = r.recognize_google(audio_listened, language='vi-VN') break except sr.UnknownValueError: print(f"分片{i}识别失败,重试第{retry_cnt+1}次") except sr.RequestError as e: print(f"接口请求失败:{e},重试第{retry_cnt+1}次") if text: formatted_text = f"{text.capitalize()}. " print(chunk_filename, ":", formatted_text) whole_text += formatted_text else: print(f"分片{i}重试{max_retry}次仍失败,跳过") return whole_text
递归版本修复(如果必须保留递归实现)
去掉原函数内的for循环,完全通过pos参数控制处理进度,避免重复执行:
def chunks_process(chunks, pos, folder_name, whole_text, max_retry=3, current_retry=0): # 所有分片处理完成返回结果 if pos >= len(chunks): return whole_text # 当前分片重试次数耗尽,跳过处理下一个 if current_retry >= max_retry: return chunks_process(chunks, pos+1, folder_name, whole_text, max_retry, 0) r = sr.Recognizer() chunk_filename = os.path.join(folder_name, f"chunk{pos}.wav") chunks[pos].export(chunk_filename, format="wav") with sr.AudioFile(chunk_filename) as source: audio_listened = r.record(source) try: text = r.recognize_google(audio_listened, language='vi-VN') except (sr.UnknownValueError, sr.RequestError): # 识别失败重试当前分片 return chunks_process(chunks, pos, folder_name, whole_text, max_retry, current_retry+1) else: text = f"{text.capitalize()}. " print(chunk_filename, ":", text) whole_text += text # 处理下一个分片 return chunks_process(chunks, pos+1, folder_name, whole_text, max_retry, 0)
调用时初始传入pos=0、whole_text=""即可。
内容的提问来源于stack exchange,提问作者Ochimot
相关产品推荐
相关产品推荐

