try-except
try:
print("step1")
a=3/0 #此处会抛出异常
print("step2")
except BaseException as e: #捕获异常 BaseException是异常的最大类
"""即捕获到BaseException类中的异常类时会将其保存为e,一般将储存信息的变量定义为e"""
print("step3")
print(e)
print("step4")
'''
step1
step3
division by zero 遇到line3的异常后,后续不在执行;捕获到异常后执行except中的语句,然后在执行外部
step4
'''
循环结合异常
while True:
try:
x=int(input("请输入数字:")) #如果输入非数字 无法转换成整型会报错
print(x)
if x==999:
break #循环的break条件
except BaseException as e: #捕获异常
print(e) #输出异常的错误信息
异常处理的else语句
a=input("请输入被除数:")
b=input("请输入除数:")
try:
a = int(a)
b = int(b)
print("商:", a / b)
'''
a与b首先需要是合适的type才能转化为整型
其次b不可以为0,不然会报除数为0的错
'''
except BaseException as e:
print(e)
print(type(e))
else: #没有发生异常才会运行的代码
print("程序运行完毕")
多个except语句
#异常处理的本质是 解释器抛出异常->捕获异常->解决异常
'''
输入被除数和除数,输出商
会出现2种异常问题
1.输入的字符并不是数字,不能转换为int
2.除数为0
解决方法
1.输入后判断isdigit()再判断!=0 但是会导致业务偏移
2.异常处理
'''
a=input("请输入被除数:")
b=input("请输入除数:")
'''
if a.isdigit() and b.isdigit():
if int(b) != 0:
a=int(a)
b=int(b)
print("商:",a/b)
'''
try:
a = int(a)
b = int(b)
print("商:", a / b)
except TypeError:
print("输入类型有误")
except ZeroDivisionError:
print("除数不能为0")
except BaseException as e: #添加后可以涵盖所有异常,属于父类,父类放在异常捕获的最后
print("其他异常")
print(e)
print(type(e))
#try将可能出现异常的代码放入,except是try内代码出现异常时执行的语句
'''
except (ValueError,Exception,ZeroDivisionError) as e: 将多种异常放在元组中,不需要注意顺序,且可以将异常储存为e输出type
type(e) 获取异常类型
e.args 获取异常信息
'''
常见异常类型
'''
1.SyntaxError
语法错误
2.NameError
尝试访问的变量未申明
3.ZeroDivisionError
除数为0
4.ValueError
数值错误,类型不可以转换 如 int("abc")
5.TypeError
类型错误,如 123+"abc" 两者不是同一类型
6.AttributeError
访问对象不存在的属性 如 a=100 a.say() say没有被定义过
7.IndexError
访问越界,常出现在循环遍历
8.KeyError
字典键不存在
'''
finally
a=input("请输入被除数:")
b=input("请输入除数:")
try:
a = int(a)
b = int(b)
print("商:", a / b)
except BaseException as e:
print(e)
print(type(e))
finally: #finally是无论如何都会执行的步骤,部分程序在报错处理后不会继续运行,所以需要finally
print("程序运行完成")
print("end")
'''
遇到在自定义方法中需要添加return语句,一律放到整个异常模块外
'''
异常处理的机制
'''
def test1():
print(">>>>>test1<<<<<")
print(aa)
print(">>>>>test1 over<<<<<")
def test2():
print(">>>>>test2<<<<<")
test1()
print(">>>>>test2 over<<<<<")
def test3():
print(">>>>>test3<<<<<")
test2()
print(">>>>>test3 over<<<<<")
test3()
以上运行结果为:
Traceback (most recent call last):
File "D:\Python practice\基本知识结构\异常处理机制.py", line 14, in <module>
test3()
File "D:\Python practice\基本知识结构\异常处理机制.py", line 11, in test3
test2()
File "D:\Python practice\基本知识结构\异常处理机制.py", line 7, in test2
test1()
File "D:\Python practice\基本知识结构\异常处理机制.py", line 3, in test1
print(aa)
NameError: name 'aa' is not defined
#>>>>>test3<<<<<
#>>>>>test2<<<<<
#>>>>>test1<<<<<
先在外部调用了test3,走完第一个print以后调用test2,在test2里先进行一个print,调用test1,test1进行一次print后遭遇异常,不会继续执行
遭遇异常后,解释器会寻找是否有异常处理的方式被定义过,由调用的顺序进行查找,可以找到调用的逻辑顺序是test3-test2-test1-print(aa) 异常处理的逻辑也是由此执行
'''
def test1():
print(">>>>>test1<<<<<")
print(aa)
print(">>>>>test1 over<<<<<")
def test2():
print(">>>>>test2<<<<<")
test1()
print(">>>>>test2 over<<<<<")
def test3():
print(">>>>>test3<<<<<")
try:
test2()
except:
pass
print(">>>>>test3 over<<<<<")
test3()
'''
>>>>>test3<<<<<
>>>>>test2<<<<<
>>>>>test1<<<<<
>>>>>test3 over<<<<<
此时不会报错,在中间调用插入try,可以使得异常处理机制向逻辑调用前端查询时被pass掉,无视该调用的异常,但是也会使得后续语句不执行
'''
自定义异常、raise抛出异常
#自定义异常类
class AgeError(Exception):
def __init__(self,errorinfo):
super(AgeError,self).__init__() #所有自定义类都需要调用父类的self定义
self.errorinfo = errorinfo
def __str__(self):
return str(self.errorinfo)+",年龄输入错误"
'''
__main__.AgeError: 180,年龄输入错误 抛出的错误信息
'''
if __name__ == "__main__": #如果是True,该模块是作为独立文件执行,一般用于测试
age = int(input("请输入年龄:"))
if (age<1 or age>150):
raise AgeError(age) #需要用到raise来抛出自定义的异常类
else:
print("年龄是{0}".format(age))
文档相关的异常处理
'''
try:
except 异常 as 变量:
else:
没有异常执行的代码
finally:
最终一定要执行的代码
'''
try:
file = open("123.txt","w+",encoding="utf-8")
file.write("Hello\n")
file.write("World")
file.write([1,2,3]) #此处会异常,因为write只能写入字符串,writelines才能写入字符串列表
except Exception as e:
print(e.args)
else:
print("写入完毕")
print("无异常") #无异常时才会执行
finally:
file.close() #close一定要放在finally中保证能够清空缓冲区,并关闭文件
print("end...")
traceback生成异常日志
import traceback #要使用traceback 需要导入模块
try:
a=3/0
except:
with open("D:\\Python practice\\基本知识结构\\异常\\异常日志.txt","a") as f:
'''
因为异常日志是自动运行时同时运作的,所以采用能自动管理资源的with语句
"a"是append 与写不同,因为是新增内容
'''
traceback.print_exc(file = f)
with的应用
#在打开资源的情况下使用with,其他情况依然是finally
try:
f = open("D:/Python practice/基本知识结构/异常/aaa.txt","r") #open("文档的绝对路径","读或写(w or r)")
content = f.readline()
print(content)
except BaseException as e:
print(e)
print(type(e))
finally:
print("closing file...")
f.close() #文件打开后必须关闭
'''
代码给到os(系统)操作命令,在硬盘中打开文档,一定要记得使用完毕,传输close命令
绝对路径标识 "/"或者"\\"
'''
print("with代码块比较>>>>>>>>>>>>>")
with open("D:/Python practice/基本知识结构/异常/aaa.txt","r") as f:
content = f.readline()
print(content)
'''
with会进行自动的上下文管理,不论是否有异常都会自动释放资源即close
在有文档操作的情况下with可以替代一整个Try代码块
'''