目录
第一个异常——除零异常
捕获异常
try-except语句
多个except代码块
多重异常捕获
try-except语句嵌套
使用finally代码块释放资源
自定义异常类
为增强程序的健壮性,我们也需要考虑异常处理方面的内容。例如 ,在读取文件时需要考虑文件不存在、文件格式不正确等异常情况。
在数学中,任何整数都不能除以0,如果在计算机程序中将整数除以0,则会引发异常。
i=input('请输入数字:') # input()函数从控制台获得用户输入的字符串
n=8888
result=n/int(i)
print(result)
print('{0}除以{1}等于{2}'.format(n,i,result))
请输入数字:10
888.8
8888除以10等于888.8
请输入数字:0
Traceback (most recent call last):
File "E:\0\pythonProject1\venv\zzzzzlll.py", line 245, in
result=n/int(i)
ZeroDivisionError: division by zero
程序运行出错时会有Traceback信息,Traceback信息是“异常堆栈信息”,描述了程序运行的过程及引发异常的信息。从运行结果看,整数除以0引发的异常是ZeroDivisionError,从后缀名(Error)来看应该将其翻译为“错误”,而不是“异常”。
注意:在Python中,异常类命名的主要后缀有Exception、Error和Warning,也有少数几个没有采用这几个后缀命名。
我们不能防止用户输入0,但在出现异常后我们能捕获并处理异常 ,不至于让程序发生终止并退出。
异常捕获是通过try-except语句实现的,基本的try-except语句的语法如下。
try:
<可能会引发异常的语句>
except[异常处理]: # 异常类型可用省略
<处理异常>
在try代码块中包含在执行过程中可能引发异常的语句,如果发生异常,则跳到except代码块执行,这就是异常捕获。 try-except语句的执行流程如下。
i=input('请输入数字:') # input()函数从控制台获得用户输入的字符串
n=8888
try:
result = n / int(i)
print(result)
print('{0}除以{1}等于{2}'.format(n, i, result))
except
print('不能除以0')
输出结果
请输入数字:0
不能除以0
从运行的结果可以看出,在输入数字0后,异常发生,跳到except代码块执行。
注意:在except语句中如果不指定具体的异常数据类型,则except语句可以捕获在try中发生的所有异常。如果指定具体的异常类型,则except语句只能捕获在try中发生的指定类型的异常。
i=input('请输入数字:') # input()函数从控制台获得用户输入的字符串
n=8888
try:
result = n / int(i)
print(result)
print('{0}除以{1}等于{2}'.format(n, i, result))
except ZeroDivisionError as e:
print('不能除以0,异常:{}'.format(e))
输出结果
请输入数字:0
不能除以0,异常:division by zero
多条语句可能会引发多种不同的异常,对每一种异常都会采用不同的处理方式。针对这种情况,我们可以在一个try后面跟多个except代码 块,语法如下:
try:
<可能会引发异常的语句>
except 异常类型1:
<处理异常>
except 异常类型2:
<处理异常>
...
except: # 省略异常类型的是默认的代码块,它只能被放到最后,捕获上面没有匹配的异常类
<处理异常>
示例代码
i=input('请输入数字:') # input()函数从控制台获得用户输入的字符串
n=8888
try:
result = n / int(i)
print(result)
print('{0}除以{1}等于{2}'.format(n, i, result))
except ZeroDivisionError as e: # 捕获0异常
print('不能除以0,异常:{}'.format(e))
except ValueError as e: # 捕获整数转换异常
print("输入的是无效数字,异常:{}".format(e))
输出结果
请输入数字:0
不能除以0,异常:division by zero
请输入数字:DFYG
输入的是无效数字,异常:invalid literal for int() with base 10: 'DFYG'
如果有多个except代码块的异常处理过程类似,则可以合并处理。
i=input('请输入数字:') # input()函数从控制台获得用户输入的字符串
n=8888
try:
result = n / int(i)
print(result)
print('{0}除以{1}等于{2}'.format(n, i, result))
except (ZeroDivisionError,ValueError) as e:
print('不能除以0,异常:{}'.format(e))
i=input('请输入数字:') # input()函数从控制台获得用户输入的字符串
n=8888
try:
i2=int(i) # 整数转换可能发生异常,需要捕获异常
try:
result = n / int(i)
print('{0}除以{1}等于{2}'.format(n, i2, result))
except ZeroDivisionError as e1:
print("不能除以0,异常:{}".format(e1))
except ValueError as e2:
print('输入的是无效数字,异常:{}'.format(e2))
有时在try-except语句中会占用一些资源,例如打开的文件、网络连接、打开的数据库及数据结果集等都会占用计算机资源,需要程序员释放这些资源。为了确保这些资源能够被释放,可以使用finally代码块。 在try-except语句后面还可以跟一个finally代码块,语法如下。
try:
<可能会引发异常的语句>
except 异常类型1:
<处理异常>
except 异常类型2:
<处理异常>
...
except: # 省略异常类型的是默认的代码块,它只能被放到最后,捕获上面没有匹配的异常类
<处理异常>
finally:
<释放资源>
无论是try代码块正常结束还是except代码块异常结束,都会执行finally代码块。
使用finally代码块的示例代码如下:
i=input('请输入数字:') # input()函数从控制台获得用户输入的字符串
n=8888
try:
result = n / int(i)
print(result)
print('{0}除以{1}等于{2}'.format(n, i, result))
except ZeroDivisionError as e: # 捕获0异常
print('不能除以0,异常:{}'.format(e))
except ValueError as e: # 捕获整数转换异常
print("输入的是无效数字,异常:{}".format(e))
finally:
print('资源释放...')
输出结果
请输入数字:15
592.5333333333333
8888除以15等于592.5333333333333
资源释放...
很多公司为了提高代码的可重用性,自己编写了一些Python类库,其中自己编写了一些异常类。实现自定义异常类,需要继承Exception类或其子类,之前遇到的ZeroDivisionError和ValueError异常都属于Exception的子类。
class ZhijieketangException(Exception): # 自定义异常类的名称
def __init__(self,message): # 构造方法,其中的参数message是异常描述信息
super().__init__(message) # 调用父类构造方法,并把参数message传给父类构造方法
class ZhijieketangException(Exception): # 自定义异常类的名称
def __init__(self, message): # 构造方法,其中的参数message是异常描述信息
super().__init__(message) # 调用父类构造方法,并把参数message传给父类构造方法
i=input('请输入数字:') # input()函数从控制台获得用户输入的字符串
n=8888
try:
result = n / int(i)
print(result)
print('{0}除以{1}等于{2}'.format(n, i, result))
except ZeroDivisionError as e: # 捕获0异常
# print('不能除以0,异常:{}'.format(e))
raise ZhijieketangException('不能除以零')
except ValueError as e: # 捕获整数转换异常
#print("输入的是无效数字,异常:{}".format(e))
raise ZhijieketangException('输入的是无效数字')