嵌套while循环捕获异常跳转外层时触发StopIteration的原因及解决
错误触发原因
- 直接原因:你代码中内层循环调用
input()读取用户输入时,如果运行环境的输入流被耗尽(比如非交互模式运行、手动输入了EOF快捷键Ctrl+D/Ctrl+Z),如果input被封装为迭代器读取的形式,迭代器耗尽就会抛出StopIteration,PDB显示的行号偏差让你误以为是print语句触发了错误,实际是下一轮内层循环走到input()时触发的。 - 代码逻辑隐患:你当前的内层循环没有处理非法输入的场景,当用户输入的内容不匹配
HIT|STAND|DOUBLE DOWN|SPLIT规则时,matched_play为空,内层循环会无限重复请求输入,永远不会跳出到外层逻辑。
修复方案
你可以按照以下逻辑调整代码,既解决异常问题,也实现「捕获BetError后返回第一层循环重新执行」的预期:
import re from time import sleep # 假设cls、BetError已经正确定义 def make_play(self, player_hand, dealer_hand): while True: print(f''' {self} 'Dealer' =============== =============== {player_hand} {dealer_hand} ''') play = None while True: input_content = input( "How would you like to play your hand?\n>>> " ).upper() matched_play = re.match(r'HIT|STAND|DOUBLE DOWN|SPLIT', input_content) if not matched_play: print("输入不合法,请输入HIT/STAND/DOUBLE DOWN/SPLIT") continue play = input_content break # 走到这里说明已经拿到合法的play选项 if play == "DOUBLE DOWN" or play == "SPLIT": try: self.bet() except BetError as e: print(f'\n{e}') print("\nCannot perform suggested play...") sleep(1) cls() # 直接continue外层循环,重新展示手牌请求输入 continue # 所有校验通过,返回选择 return play
调整点说明:
- 拆分了输入合法性校验和下注校验两个逻辑,内层循环只负责拿到合法的输入选项,避免内层循环逻辑混乱
- 捕获到BetError后直接用
continue跳转到外层循环开头,直接实现你要的重走逻辑 - 新增了非法输入的提示,避免内层死循环
内容的提问来源于stack exchange,提问作者binny
相关产品推荐
相关产品推荐

