Python的异常处理

文章目录

异常处理

程序错误分为两种:语法错误 和 异常错误
语法错误:代码没有按照python规定语法去写,发明创造产生的错误 #语法错误抑制不了
异常错误:在代码语法正确的前提下,程序报错就是异常 #异常错误可以抑制

#try…except… 基础语法 用于解决程序异常问题
#raise 可以主动抛异常,异常类可以自定义

异常的分类

IndexError 索引超出序列的范围
KeyError 字典中查找一个不存在的关键字
NameError 尝试访问一个不存在的变量
IndentationError 缩进错误
AttributeError 尝试访问未知的对象属性
StopIteration 迭代器没有更多的值
AssertionError 断言语句(assert)失败
EOFError 用户输入文件末尾标志EOF(Ctrl+d)
FloatingPointError 浮点计算错误
GeneratorExit generator.close()方法被调用的时候
ImportError 导入模块失败的时候
KeyboardInterrupt 用户输入中断键(Ctrl+c)
MemoryError 内存溢出(可通过删除对象释放内存)
NotImplementedError 尚未实现的方法
OSError 操作系统产生的异常(例如打开一个不存在的文件)
OverflowError 数值运算超出最大限制
ReferenceError 弱引用(weak reference)试图访问一个已经被垃圾回收机制回收了的对象
RuntimeError 一般的运行时错误
SyntaxError Python的语法错误
TabError Tab和空格混合使用
SystemError Python编译器系统错误
SystemExit Python编译器进程被关闭
TypeError 不同类型间的无效操作
UnboundLocalError 访问一个未初始化的本地变量(NameError的子类)
UnicodeError Unicode相关的错误(ValueError的子类)
UnicodeEncodeError Unicode编码时的错误(UnicodeError的子类)
UnicodeDecodeError Unicode解码时的错误(UnicodeError的子类)
UnicodeTranslateError Unicode转换时的错误(UnicodeError的子类)
ValueError 传入无效的参数
ZeroDivisionError 除数为零

获取错误行号和文件名(了解)
#(了解)系统底层获取行数和文件名的函数( 只有在程序异常时才能触发 )
def return_errorinfo(n):
import sys
f = sys.exc_info()[2].tb_frame.f_back
if n==1:
return str(f.f_lineno) #返回当前行数
elif n == 2:
return f.f_code.co_filename #返回文件名

1、IndexError 索引超出序列的范围

lst = [1,2,3]
lst[1000]

 
 

左边是错误类型,右边是错误的描述
在这里插入图片描述

2、KeyError 字典中查找一个不存在的关键字

dic = {"a":1,"b":2}
dic["c"]

 
 
  • 1
  • 2

在这里插入图片描述

3、NameError 尝试访问一个不存在的变量

print(jingtian112312313123123123123123123123123123s)

 
 

在这里插入图片描述

4、IndentationError 缩进错误

if 5 == 5:

print(2)

在这里插入图片描述

5、AttributeError 尝试访问未知的对象属性

class MyClass():
     a = 100
obj = MyClass()
obj.abc

 
 

在这里插入图片描述

6、StopIteration 迭代器没有更多的值

it = iter(range(3))
res = next(it)
res = next(it)
res = next(it)
res = next(it)

 
 

在这里插入图片描述

7、AssertionError 断言语句(assert)失败

assert猜的意思 , 叫断言,
如果断言是正确的没有任何反应,代码正常执行
如果是错误的直接报错,终止程序

使用assert断言是学习python一个非常好的习惯,python assert 断言句语格式及用法很简单。在没完善一个程序之前,我们不知道程序在哪里会出错,
与其让它在运行最崩溃,不如在出现错误条件时就崩溃,这时候就需要assert断言的帮助。本文主要是讲 assert 断言的基础知识
python assert断言的作用

python assert断言是声明其布尔值必须为真的判定,如果发生异常就说明表达示为假。可以理解assert断言语句为raise-if-not,用来测试表示式,其返回值为假,就会触发异常。
在这里插入图片描述

assert 5 < 3
print(111)

 
 

报错后,后面的代码不再执行
在这里插入图片描述

异常处理的语法

try … except … 来抑制错误
把有可能报错的代码放到try这个代码块当中,
如果有报错,直接执行except这个代码块
如果没有报错,不执行except这个代码块

在异常处理当中,所有的异常错误类都默认继承 BaseException Exception 普通异常的父类(了解)
我们写except时,不写异常类型,默认都是BaseException

#类型上的子父关系

from collections import Iterator,Iterable
print(issubclass(Iterator, Iterable))

 
 

迭代器是可迭代对象的子类
在这里插入图片描述

所有异常都继承于BaseException
在这里插入图片描述

1.基本语法

class MyClass():
    a = 6

try:
lst = [1,2,3]
lst[1000]
except:
pass

try:
lst = [1,2,3]
lst[1000]
except BaseException:
pass

运行
运行

捕获异常,程序就可以按照我们设计的方向运行,当有异常时,执行except的代码块;没异常时,执行try的代码块
在这里插入图片描述
在这里插入图片描述

写代码时有时只是想让代码可以跳过某些错误,继续运行下去,会直接使用异常捕获,而不标明具体要捕获的错误是什么。此时会出现告警如上图,原因如下
这时pycharm就会提示:“Too broad exception claus”
直译过来就是:“例外的条款太广泛”
原因就是except之后没有标明具体的异常。
在Python里是,try后面使用except而不带任何异常类型,或者所接异常类太宽泛。这种使用方式是支持的,代码也可以正常运行。
只是except会捕获所有的错误,所以无法识别出具体的异常信息。

解决办法,指明具体异常类

2.带有分支的异常处理

try:
    # lst = [1,2,3]
    # lst[1000]

# dic = {“a”:1,“b”:2}
# dic[“c”]

# print(lisi)

MyClass<span class="token punctuation">.</span>abc<span class="token punctuation">(</span><span class="token punctuation">)</span>

except IndexError:
print(“下标越界1”)
except KeyError:
print(“字典的键不存在2”)
except NameError:
print(“这个变量不存在的3”)
except :
print(“有异常错误4”)

运行
运行

当有多个异常分支时,执行try中的代码,遇到异常,根据异常类型,执行相应except中的代码,后续代码不再执行

在这里插入图片描述

3.处理生成器的异常报错

def mygen():
    yield 1
    yield 2
    yield 3
    return [1,2,3]

try:
gen = mygen()
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))

# 给StopIteration这个类创建出来的对象起一个别名叫e
“”"
当你打印对象时,会触发内部__str__方法,通过一些列的调用,返回出最后的返回值
“”"

except StopIteration as e:
# 可以获取返回值
print(e)

“”"
# 额外的扩展
res = str(e)
print(res , type(res) , “<======>”)
res2 = eval(res)
print(res2,type(res2))
“”"

运行
运行

在这里插入图片描述

except StopIteration as e 是给StopIteration类创建个对象,起个别名为e,通过__str__方法,打印对象,就是打印返回值
在这里插入图片描述

也可以except异常父类:
在这里插入图片描述

BaseException有__str__方法,所以只要异常被捕获后有返回值,打印对象,返回值即被打印
在这里插入图片描述
在这里插入图片描述

4.异常处理的其他写法

1 .try … except … else …

当try这个代码块当中没有报错的时候,执行 try 和 else 分支
如果try代码块有报错,就不执行else这个分支,执行except分支

try:
    # lst = [1,2,3]
    # lst[1000]
    print(123)
except:
    pass
else:
    print("执行了else分支 ... ")

 
 
运行
运行

代码没报错,执行try和else里面的代码
在这里插入图片描述

代码有报错,执行try中报错之前的代码,和except中的代码,不执行else中的代码
在这里插入图片描述

2.try … finally … 无论代码是否报错,都必须要执行的代码写在finally这个代码块当中

场景:应用在异常环境下, 保存数据或者关闭数据库等操作, 必须要在数据库程序崩溃之前执行的代码写在finally代码块中;

try:
    lst = [1,2,3]
    lst[1000]
finally:    
    print(234678)

 
 

代码中有报错,还是执行了finally中的代码
在这里插入图片描述

3.try … except … else … finally …
try:
    lst = [1,2,3]
    lst[1000]
    # print(123)

except:
print(456)

else:
print("执行了else分支 … ")
finally:
print(“执行关闭数据库操作”)

运行
运行

代码中有报错,执行try报错之前的代码,except中的代码,finally中的代码
在这里插入图片描述

主动抛异常

有时候我们需要根据报错,得到错误的信息
可以在程序的指定位置手动抛出一个异常?答案是肯定的,Python 允许我们在程序中手动设置异常,使用 raise 语句即可。
读者可能会感到疑惑,即我们从来都是想方设法地让程序正常运行,为什么还要手动设置异常呢?
首先要分清楚程序发生异常和程序执行错误,它们完全是两码事,程序由于错误导致的运行异常,是需要程序员想办法解决的;
但还有一些异常,是程序正常运行的结果,比如用 raise 手动引发的异常
在这里插入图片描述

BaseException 所有异常类的父类
Exception 普通异常类的父类
raise + 异常错误类 / 异常错误类对象 一旦抛异常,则程序会中断,下面的代码不再执行

(1) raise 基本语法

raise KeyError
raise KeyError()  #括号中跟描述信息

 
 

在这里插入图片描述

raise抛出异常,后面必须接异常类型或异常对象,否则报错
在这里插入图片描述

主动抛出异常,程序报错。一般抛异常,就将特定的异常类型写清楚
在这里插入图片描述

try:
    raise 
except:
    pass

try:
raise
except BaseException:
pass

运行
运行

(2) 自定义异常错误类

必须继承异常类的父类 BaseException

# return_errorinfo必须在报错的情况下才能触发内部相应方法获取当前行号和文件名
def return_errorinfo(n):
    import sys
    f = sys.exc_info()[2].tb_frame.f_back
    if n == 1:        
        return str(f.f_lineno)      #返回当前行数
    elif n == 2:    
        return f.f_code.co_filename #返回文件名    

# 通过主动抛出异常,来获取响应的数据
def get_info(n):
try:
raise
except:
return return_errorinfo(n)

# 自定义异常错误类
class MyException(BaseException):
def init(self,error_num,error_msg,error_filename,error_linenum):
self.error_num = error_num
self.error_msg = error_msg
self.error_filename = error_filename
self.error_linenum = error_linenum

eye = “轮回眼”
try:
if eye == “轮回眼”:
raise MyException( 404,“人类没有轮回眼”,get_info(2) , get_info(1) )

except MyException as e: # 给自定义MyException异常类的对象起个别名叫做e
print(e.error_num)
print(e.error_msg)
print(e.error_filename)
print(e.error_linenum)

运行
运行

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值