Python return报UnboundLocalError:take_command的command未赋值
报错核心原因
UnboundLocalError: local variable 'command' referenced before assignment的触发逻辑非常明确,没有隐蔽性问题:
command变量的赋值逻辑全部包裹在take_command函数的try代码块内部- 只要try块内任意环节抛出异常(比如麦克风被其他程序占用、语音识别服务连通失败、未检测到有效语音、麦克风权限不足),程序会直接跳转到except块执行pass,完全不会运行到
command = listener.recognize_google(...)这行赋值语句 - 此时函数末尾的
return command会尝试读取一个从未完成赋值的局部变量,直接触发报错 - 你原本代码里的裸
except: pass还会把所有异常信息全部吞掉,导致你看不到具体是哪一步出了问题,只能看到最后返回变量时的报错
完整修复方案
基础修复逻辑
- 在
take_command函数最开始给command设置合法的默认初始值,保证无论try块是否执行成功,变量都存在、可被读取,从根源上避免未定义引用的报错 - 替换无差别吞错的裸except,针对语音识别场景的常见异常做分别捕获,把错误信息打印出来方便定位问题
- 给语音采集环节增加超时限制,避免程序无响应卡在监听状态
- 在
run_alexa函数中增加空命令判断,识别失败返回空值时直接跳过后续逻辑,避免无意义的流程走查
修复后的关键代码段
首先是改造后的take_command函数:
def take_command(): # 初始化默认值,保证变量始终存在 command = '' try: with sr.Microphone() as source: print('listening...') # 自动适配环境噪音,提升识别准确率 listener.adjust_for_ambient_noise(source) # 设置3秒无语音超时,单段语音最长识别5秒 voice = listener.listen(source, timeout=3, phrase_time_limit=5) command = listener.recognize_google(voice) command = command.lower() if 'alexa' in command: command = command.replace('alexa', '') print(command) except sr.WaitTimeoutError: print("等待语音超时,未检测到说话内容") except sr.UnknownValueError: print("无法识别当前语音内容") except sr.RequestError: print("语音识别服务连接失败,请检查网络状态") except PermissionError: print("麦克风访问权限被拒绝,请检查系统权限设置") except Exception as e: print(f"语音采集出现未知错误: {str(e)}") return command
然后是run_alexa函数的适配改造:
def run_alexa(): command = take_command() print(command) # 识别为空时直接跳过本轮流程 if not command.strip(): return # 以下原有逻辑保持不变 if 'play' in command: song = command.replace('play', '') talk('playing ' + song) pywhatkit.playonyt(song) elif 'time' in command: time = datetime.datetime.now().strftime('%I:%M %p') talk('Current time is ' + time) elif 'who the heck is' in command: person = command.replace('who the heck is', '') info = wikipedia.summary(person, 1) print(info) talk(info) elif 'date' in command: talk('sorry, I have a headache') elif 'are you single' in command: talk('I am in a relationship with wifi') elif 'joke' in command: talk(pyjokes.get_joke()) else: talk('Please say the command again.')
额外注意事项
- 不要使用不带异常类型的裸
except: pass写法,这种写法会把内存错误、键盘中断、依赖导入失败等所有类型的异常全部静默吞掉,后续排查问题时没有任何参考信息 - 确保当前系统已经给Python运行程序开放了麦克风访问权限,系统权限限制是这类语音助手最常见的静默失败原因
- 语音识别依赖在线接口,必须保证运行环境可以正常访问对应服务,否则会触发请求错误
内容的提问来源于stack exchange,提问作者Saumya
相关产品推荐
相关产品推荐

