📅  最后修改于: 2020-09-19 13:48:11             🧑  作者: Mango
Python有许多内置的异常,当您的程序遇到错误时会引发这些异常(程序中的某些错误)。
当发生这些异常时, Python解释器将停止当前进程并将其传递给调用进程,直到对其进行处理。如果不处理,程序将崩溃。
例如,让我们考虑一个程序,其中有一个函数 A
调用函数 B
,而函数 B
又调用了函数 C
如果异常在函数 C
发生,但未在C
处理,则该异常传递给B
,然后传递给A
如果从未处理过,则会显示一条错误消息,并且我们的程序突然突然中止。
在Python,可以使用try
语句处理异常。
可能引发异常的关键操作放在try
子句中。处理异常的代码写在except
子句中。
因此,一旦捕获到异常,我们就可以选择要执行的操作。这是一个简单的例子。
# import module sys to get the type of exception
import sys
randomList = ['a', 0, 2]
for entry in randomList:
try:
print("The entry is", entry)
r = 1/int(entry)
break
except:
print("Oops!", sys.exc_info()[0], "occurred.")
print("Next entry.")
print()
print("The reciprocal of", entry, "is", r)
输出
The entry is a
Oops! occurred.
Next entry.
The entry is 0
Oops! occured.
Next entry.
The entry is 2
The reciprocal of 2 is 0.5
在此程序中,我们遍历randomList
列表的值。如前所述,可能导致异常的部分放在try
块中。
如果没有异常发生,则跳过except
块,并继续正常流程(最后一个值)。但是,如果发生任何异常,它将被except
块(第一个和第二个值)捕获。
在这里,我们使用sys
模块中的exc_info()
函数打印异常的名称。我们可以看到a
导致ValueError
而0
导致ZeroDivisionError
。
由于Python的每个异常都继承自基本Exception
类,因此我们还可以通过以下方式执行上述任务:
# import module sys to get the type of exception
import sys
randomList = ['a', 0, 2]
for entry in randomList:
try:
print("The entry is", entry)
r = 1/int(entry)
break
except Exception as e:
print("Oops!", e.__class__, "occurred.")
print("Next entry.")
print()
print("The reciprocal of", entry, "is", r)
该程序具有与上述程序相同的输出。
在上面的示例中,我们在except
子句中没有提及任何特定的例外。
这不是一个好的编程习惯,因为它将捕获所有异常并以相同的方式处理每种情况。我们可以指定except
子句应该捕获哪些异常。
try
子句可以具有任意数量的except
子句来处理不同的异常,但是,只有在发生异常的情况下才会执行一个。
我们可以使用值的元组在except子句中指定多个异常。这是示例伪代码。
try:
# do something
pass
except ValueError:
# handle ValueError exception
pass
except (TypeError, ZeroDivisionError):
# handle multiple exceptions
# TypeError and ZeroDivisionError
pass
except:
# handle all other exceptions
pass
在Python编程中,运行时发生错误时会引发异常。我们还可以使用raise
关键字手动引发异常。
我们可以选择将值传递给异常,以阐明引发该异常的原因。
>>> raise KeyboardInterrupt
Traceback (most recent call last):
...
KeyboardInterrupt
>>> raise MemoryError("This is an argument")
Traceback (most recent call last):
...
MemoryError: This is an argument
>>> try:
... a = int(input("Enter a positive integer: "))
... if a <= 0:
... raise ValueError("That is not a positive number!")
... except ValueError as ve:
... print(ve)
...
Enter a positive integer: -2
That is not a positive number!
在某些情况下,如果try
内的代码块运行无误,则可能要运行某个代码块。对于这些情况,可以在try
语句中使用可选的else
关键字。
注意 :else子句中的异常不会由前面的except子句处理。
让我们看一个例子:
# program to print the reciprocal of even numbers
try:
num = int(input("Enter a number: "))
assert num % 2 == 0
except:
print("Not an even number!")
else:
reciprocal = 1/num
print(reciprocal)
输出
如果我们传递一个奇数:
Enter a number: 1
Not an even number!
如果我们传递一个偶数,则将计算并显示倒数。
Enter a number: 4
0.25
但是,如果我们传递0, ZeroDivisionError
得到ZeroDivisionError
因为else
内的代码块不会由except
来处理。
Enter a number: 0
Traceback (most recent call last):
File "", line 7, in
reciprocal = 1/num
ZeroDivisionError: division by zero
Python的try
语句可以有一个可选的finally
子句。该子句无论如何执行,通常用于释放外部资源。
例如,我们可能通过网络或使用文件或图形用户界面(GUI)连接到远程数据中心。
在所有这些情况下,无论程序是否成功运行,我们都必须在程序停止之前清理资源。这些操作(关闭文件,GUI或与网络断开连接)在finally
子句中执行,以确保执行。
这是一个文件操作的例子来说明这一点。
try:
f = open("test.txt",encoding = 'utf-8')
# perform file operations
finally:
f.close()
这种类型的构造可确保即使在程序执行期间发生异常,也可以关闭文件。