TLDR
try/except 块确保您的程序继续运行而不是突然结束。通过包含except KeyError,我们特别确保在出现KeyError 时程序不会突然结束。如果value 不是字典中的键,result_dict[value] += 1 将抛出错误,因为它试图访问不存在的键。 += 使代码运行类似于:
result_dict[value] = result_dict[value] + 1
由于value不在result_dict中,所以类似于说
result_dict[value] = None + 1
这很糟糕。
非 TLDR 版本
当python中发生错误时,程序通常会突然终止并退出。它不会运行发生在异常发生的部分下方的任何代码。例如,采用以下代码。取用户a和b的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=4, b=2),程序就会顺利进行。但是,如果用户要给,比如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"
如果发生任何其他类型的错误,它将在最后的 except 块中结束并打印"Some unexpected error has occurred"
并且处理完异常后,打印"I am done"
请注意,如果最后的 except 块没有捕获任何其他异常,那么程序将不会很好地终止,因为该异常未处理,并且它不会打印最后的语句。
现在,人们如何意识到可能发生的错误?这取决于实践,一旦您熟悉了错误,您就可以相应地处理它们。或者,故意让您的程序抛出异常,并读取堆栈跟踪以了解发生了何种异常。然后相应地处理它们。您不必以不同的方式处理每个特定错误,您可以以相同的方式处理所有错误。
您可以在这里阅读更多内容:Python's documentation for errors and exceptions