Python 基础笔记 day-9 异常处理

这篇博客详细介绍了Python的异常处理机制,包括try-except结构、异常定位、常见异常类型及处理,以及with上下文管理和自定义异常。强调了解决异常问题时的定位技巧和PyCharm的调试方法。

异常和错误

导引

软件程序在运行过程中,非常可能遇到刚刚提到的这些问题,我们称之为异常,英文是:Exception,意思是例外。遇到这些例外情况,或者叫异常

异常机制本质

所谓异常处理,就是指程序在出现问题时依然可以正确的执行剩余的程序,而不会因为异常而终止程序执行。
python 中内建异常类的继承层次:
在这里插入图片描述

异常的结构

python 中一切都是对象,异常也采用对象的方式来处理。处理过程:

  1. 抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给解释器。
  2. 捕获异常:解释器得到该异常后,寻找相应的代码来处理该异常。
a = 3 / 0
>>>
>>>
D:\Software\ANACONDA\python.exe D:/Code_output/Python/python基础/day1.py
Traceback (most recent call last): #Traceback追溯,追根溯源。most recent call last最后一次调用。

  File "D:/Code_output/Python/python基础/day1.py", line 1, in <module>
    a = 3 / 0
ZeroDivisionError: division by zero # 0作为除数了

Process finished with exit code 1

解决异常问题的态度

解决每一个遇到的异常, 建议大家遵循如下三点:

  1. 不慌张, 细看信息, 定位错误。 看清楚报的错误信息, 并定位发生错误的地方。
  2. 百度并查看十个相关帖子。 将异常类信息进行百度, 至少查看十个以上的相关帖子。
  3. 以上两步仍然无法解决, 找老师和同学协助解决。

异常解决的关键: 定位

当发生异常时, 解释器会报相关的错误信息, 并会在控制台打印出相关错误信息。 我们只需按照从上到下的顺序即可追溯(Trackback) 错误发生的过程, 最终定位引起错误的那一行代码

def a():
    num = 1/0

def b():
    a()

def c():
    b()

c()
>>>
>>>
D:\Software\ANACONDA\python.exe D:/Code_output/Python/python基础/Python400集第一季源代码/代码异常/my01.py
Traceback (most recent call last):
  File "D:/Code_output/Python/python基础/Python400集第一季源代码/代码异常/my01.py", line 14, in <module>
    c()
  File "D:/Code_output/Python/python基础/Python400集第一季源代码/代码异常/my01.py", line 11, in c
    b()
  File "D:/Code_output/Python/python基础/Python400集第一季源代码/代码异常/my01.py", line 8, in b
    a()
  File "D:/Code_output/Python/python基础/Python400集第一季源代码/代码异常/my01.py", line 5, in a
    num = 1/0  
ZeroDivisionError: division by zero #其实只有这个错误,前面的都是过程

Process finished with exit code 1

异常处理结构

try…一个 except 结构

try 块包含着可能引发异常的代码, except 块则用来捕捉和处理发生的异常。 执行的时候, 如果 try 块中没有引发异常, 则跳过 ecept 块续执行后续代码; 执行的时候, 如果 try块中发生了异常, 则跳过 try 块中的后续代码跳到相应的 except 块中处理异常; 异常处理完后, 继续执行后续代码。

处理结构
在这里插入图片描述

#coding=utf-8
print("step0")
try:
    print("step1")
    a = 3/0
    print("step2")
except BaseException as e: #e就是一个错误类型对象
    print("step3")
    print(e)
    print(type(e))
print("end!!!!")
while True:
    try:
        x = int(input('Please enter a number:'))
        print('The number is :',x)
        if x == 88 :
            print('Quit')
            break
    except BaseException as e:
        print(e)
        print('Wrong! You shoule enter a number !!')
        print('If you want to quit, please enter number 88')

print('Program end')

try…多个 except 结构

针对不同的异常,执行不同的操作
按照先子类后父类的顺序
在这里插入图片描述

#coding=utf-8
#测试try...多个except结构

try:
    a = input("请输入一个被除数:")
    b = input("请输入一个除数:")
    c = float(a)/float(b)
    print(c)
except ZeroDivisionError:
    print("异常。不能除以0")
except ValueError:
    print("异常。不能将字符串转化成数字")
except NameError:
    print("异常。变量不存在")
except BaseException as e:
    print(e)

try…except…else 结构

try…except…else 结构增加了“ else 块” 。 如果 try 块中没有抛出异常, 则执行 else 块。 如果try 块中抛出异常, 则执行 except 块, 不执行 else 块。

#coding=utf-8
#测试try...except...else结构

try:
    a = input("请输入一个被除数:")
    b = input("请输入一个除数:")
    c = float(a)/float(b)
except BaseException as  e:
    print(e)
else:
    print(c)
print("程序结束!")

try…except…finally 结构

try…except…finally 结构中, finally 块无论是否发生异常都会被执行; 通常用来释放 try 块中申请的资源。

#coding=utf-8
#测试try...except...else...finally结构

try:
    a = input("请输入一个被除数:")
    b = input("请输入一个除数:")
    c = float(a)/float(b)
except BaseException as  e:
    print(e)
else:
    print(c)
finally:
    print("我是finally中的语句,无论发生异常与否,都执行!")
print("程序结束!")
#coding=utf-8
#测试finally

try:
    f = open("d:/adddd.txt","r")
    content = f.readline()
    print(content)
except:
    print("文件未找到")
finally:
    print("run in finally。关闭资源")
    try:
        f.close()
    except BaseException as e:
        print(e)


print("程序执行结束!")

return 语句和异常处理问题

def test01():
    print("step1")
    try:
        x = 3/0
        # return "a"
    except:
        print("step2")
        print("异常: 0 不能做除数")
        #return "b"
    finally:
        print("step4")
        #return "d"
    print("step5")
    return "e" #一般不要将 return 语句放到 try、 except、 else、    finally 块中, 会发生一些意想不到的错误。 建议放到方法最后。
    
print(test01())

常见异常的解决

  1. SyntaxError: 语法错误
  2. NameError: 尝试访问一个没有申明的变量
  3. ZeroDivisionError: 除数为 0 错误(零除错误)
  4. ValueError: 数值错误
  5. TypeError: 类型错误
  6. AttributeError: 访问对象的不存在的属性
  7. IndexError: 索引越界异常
  8. KeyError: 字典的关键字不存在

常见异常汇总

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

with 上下文管理

finally 块由于是否发生异常都会执行, 通常我们放释放资源的代码。 其实, 我们可以通过 with 上下文管理, 更方便的实现释放资源的操作。
在这里插入图片描述
with 上下文管理可以自动管理资源, 在 with 代码块执行完毕后自动还原进入该代码之前的现场或上下文。 不论何种原因跳出 with 块, 不论是否有异常, 总能保证资源正常释放。 极大的简化了工作, 在文件操作、 网络通信相关的场合非常常用。

#coding=utf-8
#测试with上下文管理(with不是用来取代try...except...finally结构的,只是作为补充。方便我们再文件管理、网络通信时的开发)

with open("d:/a.txt","r") as f:
    content = f.readline()
    print(content)

print("程序执行结束!")

trackback 模块

追溯模块,帮助我们更方便的打印异常信息

#coding=utf-8
#测试trackback模块的使用
import traceback

try:
    print("step1")
    num = 1/0
except:
    traceback.print_exc()

#######将异常信息输出到指定的文件中########
try:
    print("step1")
    num = 1/0
except:
    with open("d:/a.txt","a") as f:
        traceback.print_exc(file=f)

自定义异常类

程序开发中, 有时候我们也需要自己定义异常类。 自定义异常类一般都是运行时异常, 通常继承 Exception 或其子类即可。 命名一般以 Error、 Exception 为后缀。
自定义异常由 raise 语句主动抛出

#coding=utf-8
#测试自定义异常类

class AgeError(Exception):  #继承Exception
    def __init__(self,errorInfo):
        Exception.__init__(self)
        self.errorInfo = errorInfo
    def __str__(self):
        return str(self.errorInfo)+",年龄错误!应该在1-150之间"


############测试代码################
if __name__ == "__main__":   #如果为True,则模块是作为独立文件运行,可以执行测试代码
    age = int(input("输入一个年龄:"))
    if age<1 or age>150:
        raise AgeError(age)
    else:
        print("正常的年龄:",age)

Pycharm 开发环境的调试

关键:设置断点
调试视图(debug):shift+F9
调试操作
在这里插入图片描述
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值