为什么Python中的try/except需要一个except块?

2024-05-08 17:03:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道它的作用,但我不明白我们为什么要这么做?为什么我们要试着去做些什么

例如:

    for i, value in enumerate(arr):
        try:
            result_dict[value] += 1
        except KeyError:
            result_dict[value] = 1

除了keyrerror,我为什么还要做其他事情?我不知道为什么会抛出KeyError。为什么我不能这么做

result_dict[value] += 1

首先

除了尝试/捕获之外,还有什么进入块内?我知道必须抛出错误,但是在except块内必须执行什么条件

对不起,如果我的问题太愚蠢了。我是初学者


Tags: inforvalue错误result条件事情dict
3条回答

如果result_dict[value]不存在,KeyError将使程序崩溃/终止。通过使用except块,您可以告诉程序在发生KeyError时应该做什么(在这里,如果不存在result_dict[value] = 1),然后程序继续。基本上,你是在避免撞车

假设你的value"banana"。如果没有result_dict["banana"],则不能将1添加为零,即None += 1

通过使用except KeyError,您可以在错误停止程序之前拦截它,现在您已经为result_dict设置了一个键值对,而不是终止程序

原因如下。你不能添加到没有的东西上。例如说var1 = None。我不能做像var = var + 1这样的事情。那会造成错误。在您共享的示例中,代码将检查您是否可以向值的键添加1。如果无法执行此操作,请为该键指定一个值

for i, value in enumerate(arr):
        try:
            #Try and add 1 to a dict key's value. 
            result_dict[value] += 1
        except KeyError:
            #Say we get an error we need to assign the dict key's value to 1.
            result_dict[value] = 1

TLDR

try/except块确保程序继续运行,而不是突然结束。通过包含except KeyError,我们特别确保在发生KeyError时程序不会突然结束^如果value不是字典中的键,则{}将抛出错误,因为它尝试访问不存在的键。+=使代码的运行方式类似于:

result_dict[value] = result_dict[value] + 1

既然{}不是结果,它类似于说

result_dict[value] = None + 1

这很糟糕

非TLDR版本

当python中发生错误时,程序通常会突然终止并退出。它不会运行发生异常的部分下面的任何代码。例如,以下面的代码为例。它从用户ab获取2个数字,并输出a/b

a = int(input("Enter a value for a: "))
b = int(input("Enter a value for b: "))

print("a/b is:", a/b)

如果用户提供了有效的输入(比如^{),程序将顺利进行。但是,如果用户要给出,比如a = "c",则会发生以下情况

Traceback (most recent call last):
  File "<string>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'c'

节目突然结束了。让程序以这样的方式结束是完全有效的,但您很少希望程序突然结束。以用户有1000个输入为例,最后一个输入出错。由于程序突然结束,用户必须重新启动程序并重新输入所有1000个输入

现在我们介绍一个try/except块。我们知道,将非数字字符转换为整数将抛出一个ValueError,如错误中所示,因此我们将相应地处理它们

while True:
    try:
        a = int(input("Enter a value for a: "))
        break
    except:
        print("An error has occurred. Please input a again")

while True:
    try:
        b = int(input("Enter a value for b: "))
        break
    except:
        print("An error has occurred. Please input b again")

print("a/b is:", a/b)

现在,我们从用户那里获取一个输入,尝试将其转换为整数,并将该值放入a。如果成功,它将顺利进入下一行(break)并退出循环。如果失败,则将发生异常,并将进入except块,在该块中打印一条有用的错误消息,然后再次运行循环(直到用户输入有效的输入)。现在,程序不会在失败时突然终止。它向用户提供适当的反馈,并允许用户再次重试输入

这是一个通用异常块,您可以在其中捕获任何异常

但是现在让我们说,可能会发生多个错误。以下面的代码为例:

a = input()
b = input()

print(int(a)/int(b))
print("I am done")

现在可能会出现一些错误。其中之一是上面提到的ValueError,其中给定的输入不能转换为整数。另一个错误是ZeroDivisionError,其中b=0。Python不喜欢除以零,因此它会抛出异常并立即终止程序

现在,您需要为每种类型的程序打印一条特殊消息。如何做到这一点是通过捕获特定异常来实现的

a = input("Enter a value for a: ")
b = input("Enter a value for b: ")

try:
    print(int(a)/int(b))
except ValueError:
    print("We cannot convert a non-numeric character to an integer")
except ZeroDivisionError:
    print("We cannot divide by 0")
except:
    print("Some unexpected error has occurred")

print("I am done")

如果python无法将输入转换为整数,它将输入代码的ValueError块,并打印"We cannot convert a non-numeric character to an integer"

如果python试图除以0,那么它将进入ZeroDivisionError块并打印"We cannot divide by 0"

如果发生任何其他类型的错误,它将在最后的块和打印之外结束"Some unexpected error has occurred"

处理完异常后,它会打印"I am done"

请注意,如果最终的except块不在那里捕获任何其他异常,那么程序将不会很好地终止,因为该异常未经处理,并且不会打印最终语句

现在,人们如何认识到可能发生的错误?这取决于实践,一旦您熟悉了错误,就可以相应地处理它们。或者,有目的地让程序抛出异常,并读取堆栈跟踪以了解发生的异常类型。然后相应地处理它们。您不必以不同的方式处理每个特定错误,您可以以相同的方式处理所有错误

您可以在此处阅读更多内容:Python's documentation for errors and exceptions

相关问题 更多 >