异常:
一、认识异常:
1.什么是异常:
异常是指在程序运行过程中发生的异常事件,通常是由外部问题(如硬件错误、输入错误)所导致的。注意异常与错误的区别:异常时程序运行的过程中出现的,而错误是编译时产生的。广义上,异常分为两类Error和Except。
2.异常举例
先看下面这段代码:
# 例1:
num01 =int(input("请输入一个数字:"))
num02 =int(input("请输入一个数字:"))
print(num01/num02)
# 例2:
list01 = [11,22,33,44,55,66]
print(list01[8])
分析:
先说例1,例1在我们运行的过程中也许不会出错,但是一旦我们给num01和num02传入的是非数字,或者是给num02传入0,程序会立马报错并停止运行,这是异常;再看例2,我们在编写这段程序的时候,并没有提示出错,说明编译没有出错,但是当我们运行这段代码后,会提示下标越界,这也是异常。
可能你会觉得这些错误很可笑,不会出错,那是因为现在你所编写的代码的长度和复杂度不够,在足够大的项目里,里边可能会出现很多异常,而我们并不能及时的发现,更甚是还有一些异常是由于系统出现故障引起的。
二、解决异常的反法
1.条件选择语句:
对于一些简单的异常,我们可以采用条件选择语句处理,就以上例中的例1为例:
num01 =input("请输入被除数:")
num02 =input("请输入除数:")
if num01.isdigit() and num02.isdigit():
num01 = int(num01)
num02 = int(num02)
if num02 != 0:
print("%d / %d = %.2f" % (num01,num02,num01/num02))
else:
print("除数为零,出现异常!")
else:
print("输入的数据不是整数!")
用这种方法只能解决异常大家庭中的极少数的异常。因此,我们也很少使用这种方法去处理异常。通常我们所说的异常处理包含两类:
'''
异常处理在代码中主要有两种方式: 1. 异常捕获 2. 抛出异常
异常捕获有以下几种方式:
1. try --- except
2. try --- except --- else
3. try --- except --- finally
4. try --- except --- else --- finally
抛出异常:使用raise关键字来抛出异常
'''
2. 捕获异常
-
使用try — except捕获异常
""" # 使用方法: try: 有可能出现异常的代码 except: 解决方法 """ # 案例: import traceback list01 = [11,22,33,44,55,66,7,8,9] try: print(list01[len(list01)]) except Exception as e: print("访问集合的元素出现异常!请联系管理员!") print(str(e)) #反馈异常的基本信息 print(e) #反馈异常的基本信息 print(e.args[0]) #反馈异常的基本信息 print(repr(e)) #反馈异常类和异常的基本信息 print(traceback.format_exc()) #获取异常的详细信息 traceback.print_exc(file = open(".txt","w")) # 运行结果: 访问集合的元素出现异常!请联系管理员! list index out of range list index out of range list index out of range IndexError('list index out of range') Traceback (most recent call last): File "D:/mypycharm/pythonProject/千峰培训/day1/01_demo.py", line 80, in <module> print(list01[len(list01)]) IndexError: list index out of range
这种异常处理中,我们一般会采用最后一种,记录异常信息,因为有些程序我们不能时时刻刻的盯着,这种情况,采用这种方式,就会起到很好的效果。
-
具体化异常处理函数
""" # 使用方法: try: 有可能出现异常的代码 except: 解决方法 else: 未出现异常执行的代码 """ import traceback str = True while str: try: num01 = int(input("请输入被除数:")) num02 = int(input("请输入除数:")) print("%d / %d = %.2f" % (num01, num02, num01 / num02)) str = False except ValueError as e: print("输入的不是整数!") except ZeroDivisionError as e: print("输入的除数为零!") except Exception as e: print("未知的异常,具体查看日志!") traceback.print_exc(file= open("D:\mypycharm\systemlogError.txt","w")) else: print("程序正常运行,没有出现异常!")
-
使用 try — except — finally 捕获异常
try: num01 = int(input("请输入被除数:")) num02 = int(input("请输入除数:")) print("%d / %d = %.2f" % (num01, num02, num01 / num02)) except: print("代码出现异常!") finally: print("=== finally中的代码!===")
运行代码:
请输入被除数:18 请输入除数:0 代码出现异常! === finally中的代码!=== 请输入被除数:18 请输入除数:3 18 / 3 = 6.00 程序正常运行,没有出现异常! ====finally===
注意: 无论try中代码是否异常,finally中的代码都会执行;finally代码主要对资源的回收:打开文件的关闭,或者打开数据之后的关闭连接
案例;
try: global fd fd = open ("C:\\Users\\42079\\PycharmProjects\\testTT\\ystemlogError.txt",encoding="UTF-8") print(fd) except FileNotFoundError as e: print("文件路径或名字错误!") except UnicodeDecodeError as e: print("编码无法识别!") except Exception as e: print("其他未知异常!") finally: fd.close()
-
方法4: 使用 try — except — else — finally 捕获异常
while str: try: num01 = int(input("请输入被除数:")) num02 = int(input("请输入除数:")) print("%d / %d = %.2f" % (num01, num02, num01 / num02)) str = False except ValueError as e: print("输入的不是整数!") except ZeroDivisionError as e: print("输入的除数为零!") except Exception as e: print("未知的异常,具体查看日志!") traceback.print_exc(file = open("C:\\Users\\42079\\PycharmProjects\\testTT\\ystemlogError.txt","w")) else: print("程序正常运行,没有出现异常!") # 未出现异常执行的代码 finally: print("====finally===")
3. 抛出异常:
案例: 对两个0-10000之间的数进行运算
# 产生了异常,使用raise抛出异常
def div(num01:int,num02:int):
if num01 > 10000 or num01 < 0 or num02 > 10000 or num02 < 0:
raise Exception("输入的数不在范围内!")
# 可以直接使用raise抛出异常,也可以使用完整的抛出异常的方法抛出异常
try:
return num01/num02
except ZeroDivisionError as e:
raise e
if __name__ =='__main__':
str01 = True
while str01:
try:
num01= int((input("请输入0-10000之间的整数:")))
num02= int((input("请输入0-10000之间的整数:")))
print("%d / %d = %.2f" % (num01, num02, div(num01,num02)))
str = False
# 以下3中方式是接收方法中可能抛出的异常
except ValueError as e:
print("输入的数不是整数!")
except ZeroDivisionError as e:
print("输入的除数为零!")
except Exception as e:
print(str(e))
# 正确的代码,也就是不会出现异常的代码
else:
print("%d + %d = %d" % (num01, num02, num01 + num02))
print("%d - %d = %d" % (num01, num02, num01 - num02))
print("%d * %d = %d" % (num01, num02, num01 * num02))
str01 = False
print()
# 代码从主函数里开始,自伤而下运行,先执行try中的代码块,如果出现异常,就会抛出异常,else内的代码不会执行,直到异常消除位为止。
运行结果:
请输入一个0-10000之间的整数:10001
请输入一个0-10000之间的整数:-1
输入的数不在范围内!
请输入一个0-10000之间的整数:9999
请输入一个0-10000之间的整数:0
输入的除数为零!
请输入一个0-10000之间的整数:9999
请输入一个0-10000之间的整数:9999
9999 / 9999 = 1.00
9999 + 9999 = 19998
9999 - 9999 = 0
9999 * 9999 = 99980001
Process finished with exit code 0
4、自定义异常
1.自定义异常的.py文件myexceptions,定义密码长度异常类
class LenghtError(Exception):
def __init__(self,x,y):
self.x = x
self.y = y
def __str__(self):
return f"长度必须在{self.x}到{self.y}之间"
2、在另一个文件中实现我们需要实现的功能代码块,输入密码,如果密码长度不满足长度要求,抛出异常
from myexceptions import LenghtError # 引入自定义文件中的类
# 完成功能
password = input("请输入你的密码:")
m = 30
n = 6
if n <= len(password)<=m:
print("密码正确!")
else:
raise LenghtError(n,m)