Python基础刻意练习——Day11:异常处理

Day1:变量、运算符与数据类型
Day2:条件与循环
Day3&4:列表与元组
Day5:字符串与序列
Day6&7:函数与Lambda表达式
Day8:字典与集合
Day9&10:文件与文件系统
Day11:异常处理——>本文
Day12:else 与 with 语句
Day13&14:类与对象
Day15&16:魔法方法
Day17:模块

异常处理

1.异常

即便Python程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。

下面介绍一些常见的异常:

  • ImportError 导入模块失败
  • IndexError 索引超出序列的范围
  • KeyError 字典中查找一个不存在的关键字
  • MemoryError 内存溢出(可通过删除对象释放内存)
  • NameError 尝试访问一个不存在的变量
  • NotImplementedError 尚未实现的方法
  • OSError 操作系统产生的异常(例如打开一个不存在的文件)
  • OverflowError 数值运算超出最大限制
  • SyntaxError Python的语法错误
  • IndentationError 缩进错误
  • TabError Tab和空格混合使用
  • SystemError Python编译器系统错误
  • TypeError 不同类型间的无效操作
  • UnicodeError Unicode相关的错误(ValueError的子类)
  • UnicodeEncodeError Unicode编码时的错误(UnicodeError的子类)
  • UnicodeDecodeError Unicode解码时的错误(UnicodeError的子类)
  • UnicodeTranslateError Unicode转换时的错误(UnicodeError的子类)
  • ValueError 传入无效的参数
  • ZeroDivisionError 除数为零

2.错误处理机制try…except…

当我们认为某些代码可能会出错时,就可以用try来运行这段代码
如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即except语句块,执行完except后,如果有finally语句块,则执行finally语句块;
否则,忽略except子句,try子句执行后就去执行finally语句块

  • 一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。
    最多只有一个分支会被执行。
  • 若一个except子句想同时处理多个异常,可以将这些异常放在一个括号里成为一个元组一起判断
  • 最后一个except子句可以忽略异常的名称,它将被当作通配符使用
    但在实际编写程序时不建议使用,因为会把类似Ctrl+C强制中断命令所引起的异常也捕获,使其达不到想要的效果
  • finally为可选子句,可不写
while True:
    try:
        a=20
        b=int(input('请输入除数:\n'))
        print('20/%d=%d'%(a,a/b))
        break
    except ZeroDivisionError:
        print('除数不能为0,请重新输入')
    except:
        print('输入不规范,请重新输入')
    finally:
        print('--------------------')
'''
请输入除数:
0
除数不能为0,请重新输入
--------------------
请输入除数:
*
输入不规范,请重新输入
--------------------
请输入除数:
10
20/20=2
--------------------
'''
  • 除了finally,还有一个可选子句为else,else中的代码块只在try中的代码无异常运行完后执行,若有异常则不执行
  • Python的错误其实也是class,所有的错误类型都继承自BaseException
    所以在使用except时需要注意的是,它不但捕获该类型的错误,还把其子类也“一网打尽”。
    比如,将except ValueError写在except UnicodeError之前
    将永远也捕获不到UnicodeError,因为UnicodeError是ValueError的子类,如果有,也被第一个except给捕获了。
  • 使用try…except可以跨越多层函数调用

2.抛出异常

Python 使用 raise 语句抛出一个指定的异常

raise NameError('noname')

在这里插入图片描述

  • raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。
  • 如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。

3.自定义异常

可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类

class MyError(Exception):
    def __init__(self, value):
            self.value = value
    def __str__(self):
            return repr(self.value)
   
try:
    raise MyError(2*2)
except MyError as e:
    print('My exception occurred, value:', e.value)
   
#My exception occurred, value: 4

4.记录异常

如果不捕获错误,自然可以让Python解释器来打印出错误堆栈,但程序也被结束了。既然我们能捕获错误,就可以把错误堆栈打印出来,然后分析错误原因,同时,让程序继续执行下去。
可以用Python内置的logging模块记录错误信息
同样是出错,但程序打印完错误信息后会继续执行,并正常退出

while True:
    try:
        a=20
        b=int(input('请输入除数:\n'))
        print('20/%d=%d'%(a,a/b))
        break
    except ZeroDivisionError as e:
        print('除数不能为0,请重新输入',e)
        logging.exception(e)
'''
请输入除数:
0
除数不能为0,请重新输入 division by zero
ERROR:root:division by zero
Traceback (most recent call last):
  File "/Users/lql70/Desktop/VScode/python/Practise/3.py", line 18, in 
    print('20/%d=%d'%(a,a/b))
ZeroDivisionError: division by zero
请输入除数:
'''

你可能感兴趣的:(python基础)