try/except 块的范围

Scope of a try/except block

我知道 try/except 块没有单独的作用域,我也知道这个问题的实际解决方案,尽管我想知道为什么会这样。我正在为我的 sdev class 制作一个简单的猜谜游戏,虽然我可以在 try/except 块之前添加 guess_num 使其工作,但为什么我也有?

我让它循环回到主程序,但是如果我通过程序并且不输入数字作为输入,它最终会再次将我带回输入,但是如果我然后输入数字,它会给出我这个错误:

Traceback (most recent call last):
  File "C:\Users\Jexxy\Documents\MyRepo\Guessing_Game.py", line 35, in <module>
    main()
  File "C:\Users\Jexxy\Documents\MyRepo\Guessing_Game.py", line 31, in main
    if guess_num > 0 and guess_num < 100 and isinstance(guess_num, int):
UnboundLocalError: local variable 'guess_num' referenced before assignment
def main():
    random_num = random.randrange(1, 5)
    try:
        guess_num = int(input('''Welcome to the guessing game!
                 A Random number between 1-100 has already been generated!
                 When ready, please enter a number between 1-100 to make your guess: '''))
    except ValueError:
        try_again = input("You must enter a number! Try again? Y/N: ")
        if try_again.lower() == "y":
            main()
        else:
            exit(0)

    if guess_num > 0 and guess_num < 100 and isinstance(guess_num, int):
        print(guess_num)

当你 loop back to main 因为你故意输入了无效的输入,最终 main() 退出并且你在调用后又回来了。正是在这一点上,函数下降到 if guess_num ... 行并且 guess_num 未定义。

首先,您不应该对解决方案使用递归,其次,为了避免错误,请在 main().

之后添加一个 return

除了像函数或 class 之外,没有特定的范围可以尝试和排除。但是当你完成尝试时,你不会去 except 你去下一个不在 except 中的代码。这就是为什么你也会收到错误的原因,因为如果你不去除非你没有在内存中分配一个名为 try_again 的变量。

如果您得到 ValueError,您再次调用 main,该实例将进行计算。但是当那个实例 returns 时,你又回到了原始的 main,它没有为 guess_num 分配任何东西。这个原始实例尝试比较,并得到异常。每次调用 main 都会为局部变量创建自己的作用域。它不是 try/except 作用域,它是被调用的函数作用域。

解决办法是return异常情况。您已经在其中一个递归调用中打印了 guess_num,因此无需执行其他操作。

def main():
    random_num = random.randrange(1, 5)
    try:
        guess_num = int(input('''Welcome to the guessing game!
                 A Random number between 1-100 has already been generated!
                 When ready, please enter a number between 1-100 to make your guess: '''))
    except ValueError:
        try_again = input("You must enter a number! Try again? Y/N: ")
        if try_again.lower() == "y":
            main()
            return
        else:
            exit(0)

    if guess_num > 0 and guess_num < 100 and isinstance(guess_num, int):
        print(guess_num)

guess_num 仅在 input()int() 成功时设置。如果其中任何一个抛出异常,Python 没有值分配给 guess_num.

你真正的错误是使用递归。当您处理异常时,您再次调用 main() 。最后,main() returns 并且代码从您调用 main() 的地方继续。每个对 main() 的递归调用都有自己的一组局部变量,因此到 main() returns 时,main() 的所有成功 运行 都消失了,取他们的局部变量。即使在其中一个递归调用中设置了 guess_num,它也无法存在于父函数 运行.

所以真正发生的是这样的:

  1. 您输入了一个非整数值,引发了异常
  2. 你调用 main(),这次 运行 你的代码成功了。
  3. main() returns,现在您尝试访问局部变量 guess_num,但它从未被设置。

不要使用递归。使用循环。或者,如果您必须使用递归,请使用 return main(),以便在对 main() 的递归调用结束后函数退出。