python学习笔记DAY22(异常处理)

这是我个人的学习笔记,都赖于(egon老师)的分享,以下是老师博客的原地址:
https://www.cnblogs.com/xiaoyuanqujing/articles/11640888.html

异常处理

一、什么是异常

异常是程序发生错误的信号。程序运行一旦出现错误,就会抛出异常,运行终止。

异常信息通常包括:异常追踪信息、异常类型、异常信息说明

错误种类:

  1. 语法上的错误:SyntaxError,这种错误根本不应该犯,如果发现必须及时改正
  2. 常见逻辑错误:
1+"2" # 类型错误:数字与字符串不能相加
# TypeError: unsupported operand type(s) for +: 'int' and 'str'

int("nida123") # 值错误:当字符串中有非数字的值时,无法转成int类型
# ValueError: invalid literal for int() with base 10: 'nida123'

x  # 名称错误:引用了一个不存在的名字 x
# NameError: name 'x' is not defined

l = ["nida",20]  # 索引错误:索引超出列表的限制
l[3]  # IndexError: list index out of range

dic = {"name":"nida"}  # key值出错:引用了一个不存在的key
dic["age"] # KeyError: 'age'

class Foo:  # 属性错误:引用了一个不存在的属性
    pass
Foo.x   # AttributeError: type object 'Foo' has no attribute 'x'

1/0 # 除零错误:零不能做除数
# ZeroDivisionError: division by zero

二、处理异常

为了保证程序的容错性与可靠性(即,在遇到错误时有相应的处理机制不会任由程序崩溃),我们需要对异常进行处理:

try:
    被检测的代码块
except 异常类型:
    如果检测到异常,就执行这部分代码,而不会报错。

实例1:

try:
    print(x)  # 引用了一个不存在的变量
except NameError as e: # as语法,将异常说明 的值复制给变量
    print(f"NameError:{e}")  # 打印错误原因
print("这是捕捉完异常之后的代码")
# 结果输出:NameError:name 'x' is not defined
# 结果输出:这是捕捉完异常之后的代码
  • 本来程序一旦出现异常就整体结束了,有了异常处理以后,在被检测代码块出现异常时,紧跟异常的代码不会执行。开始执行except代码块。之后的代码继续正常运行。
  • 当被检测的代码块中有可能触发不同类型的异常时:(从上到下依次查找,知道找到对应错误类,否则报错)
try:
    被检测的代码块
except NameError as a: 
    触发NameError时,对应的处理逻辑
except IndexError as b: 
    触发IndexError时,对应的处理逻辑
except KeyError as c: 
    触发KeyError时,对应的处理逻辑
  • except:如果我们想多种类型异常同意用一种逻辑处理,可以将多个异常放到一个元组内,用一个except匹配
try:
    被检测的代码块
except (NameError,IndexError,KeyError) as e:
    触发NameError,IndexError,KeyError时,对应的处理逻辑
  • Exception:捕获所有异常并用的一种逻辑处理,python提供了一个万能Exception
try:
    被检测的代码块
except NameError:
    触发NameError时对应的处理逻辑
except IndexError:
    触发IndexError时对应的处理逻辑
except Exception:
    其他类型的异常统一用此处的逻辑处理
  • else:在多分支之后还可以跟一个else,只有在被检测代码没有处罚任何异常的情况下,才会执行else的子代码块
  • finally:此外,try还可以直接和finally连用,finally可以直接用在try/except/else 之后,无论被检测代码块是否发生异常,都会执行finally的子代码块,通常用于做一些回收资源的操作,关闭打开文件,关闭数据库连接等等
try:
   被检测的代码块
except 异常类型1:
   pass
except 异常类型2:
   pass
......
else:
   没有异常发生时执行的代码块
finally:
   无论有无异常发生都会执行的代码块
  • raise:自定义错误,在某些异常是python无法自动触发时,属于程序员自己制定的种种规则,这时就需要程序员自己来规定如何算触发异常。使用raise语句:
class Student:
    def __init__(self,name,age):
        if not isinstance(name,str):
            raise TypeError("名称必须是字符串")
        if not isinstance(age,int):
            raise TypeError("年龄必须是int类型")
  • 自定义异常:在内置异常不够用的情况下,我们可以通过内置的异常类来自定义
class PoolEmptyError(Exception): # 可以通过继承Exception来定义一个全新的异常
    def __init__(self,value='The proxy source is exhausted'): # 可以定制初始化方法
        super(PoolEmptyError,self).__init__()
        self.value=value

    def __str__(self): # 可以定义该方法用来定制触发异常时打印异常值的格式
        return '< %s >' %self.value


class NetworkIOError(IOError): # 也可以在特定异常的基础上扩展一个相关的异常
    pass


raise PoolEmptyError # __main__.PoolEmptyError: < The proxy source is exhausted >
raise NetworkIOError('连接被拒绝') # __main__.NetworkIOError: 连接被拒绝
  • 最后,Python还提供了一个断言语句assert expression,断定表达式expression成立,否则触发异常AssertionError,与raise-if-not的语义相同,如下
age='18'

# 若表达式isinstance(age,int)返回值为False则触发异常AssertionError
assert isinstance(age,int)

# 等同于
if not isinstance(age,int):
   raise AssertionError

三、何时使用异常处理

异常处理并不适合在所有位置使用,如果我么可以预知的错误,直接使用if...else...就可以了。

如果错误发生条件”不可预知“,但是一定会触发异常,那么就应该使用try..except语句来处理。

  • 例子:我们编写一个下载网页内容的功能,网络延迟之类的异常是正常的,而我们根本无法预知会由什么条件下会引发延迟,所以只能用异常处理机制。
posted @ 2021-06-03 11:08  nida  阅读(156)  评论(0)    收藏  举报