Python try/except块定义变量触发UnboundLocalError问题咨询
报错根本原因
该报错由「递归调用的独立栈上下文特性」+「首次函数调用内变量未完成赋值」两个原因共同触发,具体流程如下:
- 首次调用
main()时,try块内输入非数字触发ValueError,guess_num = int(...)赋值操作直接失败,当前main调用的上下文里,guess_num从未被成功绑定过值。 - 进入
except块后你选择重试触发main()调用,这是完全独立的新函数调用,会生成全新的栈帧,和第一次调用的main互不干扰:新的main输入合法数字后,只会赋值自己栈帧内的guess_num,执行完自己的全部逻辑后就会退出,回到第一次调用的main的except块之后的代码行。 - 此时回到首次调用的
main上下文,需要执行if guess_num > 0...的判断逻辑,但当前上下文的guess_num从来没有被成功赋值,自然触发UnboundLocalError。
提前定义变量有效的原因
如果在try块之前就给guess_num赋初始值,就算try块赋值失败,后续判断时该变量已经完成过绑定,就不会触发未绑定报错。但要注意:这种方案只是解决了报错,你的递归重试逻辑本身仍然有问题——重试时新调用的main里的猜测结果不会返回给上层调用,上层判断用的还是初始值,逻辑并不通顺。
更合理的实现方案
不要用递归做输入重试逻辑,改用循环即可从根源避免该问题,参考代码如下:
import random def main(): random_num = random.randrange(1, 101) while True: try: guess_num = int(input('''欢迎来到猜数字游戏! 程序已经生成了1-100之间的随机数! 准备就绪后,请输入1-100之间的整数进行猜测: ''')) # 输入类型合法直接跳出循环 break except ValueError: try_again = input("您必须输入数字!是否重试?Y/N:") if try_again.lower() != "y": exit(0) # 走到此处guess_num必然已经完成合法赋值 if 0 < guess_num < 100: print(guess_num)
内容的提问来源于stack exchange,提问作者Jexxy
相关产品推荐
相关产品推荐

