Python异常&上下文

异常

当我们的程序发生一些解释器无法继续处理下去的事情,我们的解释器无法执行无法编译,这时会抛出错误 (异常 ) 一般的异常是一些逻辑错误语法错误无法生成结果 等 抛出错误(异常 )之后,我们的程序将无法正常执行下去(抛出的错误会使我们的程序(一般是终止 )做错误的默认处理) 但是我们也可以自己去改写 出现错误之后的默认处理动作 ,也叫做捕获异常;这么做的目的就是为了提高我们程序的健壮性,应对各种复杂的互联网计算机环境


一些常见的异常

尝试访问未声明变量

python 复制代码
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

除数为0

python 复制代码
>>> 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

语法错误

python 复制代码
>>> if
  File "<stdin>", line 1
    if
     ^
SyntaxError: invalid syntax

访问字典中不存在的key值

python 复制代码
>>> mydict = {1:'a',2:'b'}
>>> mydict[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 3

索引超出范围

python 复制代码
>>> mylist = [1,2,3,4,5]
>>> mylist[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

访问未知的对象属性

python 复制代码
>>> mylist = [1,2,3,4,5]
>>> mylist[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

缩进错误

python 复制代码
>>> a = 1
>>> if a == 1:
... print 'a==1'
  File "<stdin>", line 2
    print 'a==1'
        ^
IndentationError: expected an indented block

异常捕获

将可能发生错误的语句写到try 语句部分,使用except 语句捕获对应异常,如果不明确捕捉的异常,可使用Exception将所有异常列为被捕捉对象

python 复制代码
try:
    语句
except 异常:
    捕获异常后的执行语句

python 复制代码
>>> def func():
...     print(1 / 0)
...
>>> func()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in func
ZeroDivisionError: division by zero

python 复制代码
>>> try:
...     func()
... except ZeroDivisionError:
...     print('除数为0')
...
除数为0

try...finally

python 复制代码
try:
    语句
except Exception:
    捕获异常后的执行语句
finally:
    不管异常抛出,都将执行这里的语句

python 复制代码
>>> def func():
...     print(1 / 0)
...
>>> try:
...     func()
... except Exception:
...     print('出错了')
... finally:
...     print('finally')
...
出错了

try...else

我们一般在else 语句中执行关闭套接字,关闭文件句柄,线程,进程资源释放,做一些对象内存释放的工作 为什么不在finally中呢?这是因为可能因为异常抛出,我们对应的资源句柄连创建都没有完成,也就没有必要对应的释放

python 复制代码
try:
    语句
except Exception:
    捕获异常后的执行语句
else:
    这里语句只在没有异常触发时执行

python 复制代码
>>> try:
...     1 / 0
... except Exception:
...     print('Error')
... else:
...     print('没有出错')
...
Error

在异常捕获时,我们一般使用else 语句与finally 语句配合使用;finally 语句被用作最终结束工作,做一些提示或日志写入等,而else常用在被捕获语句成功执行后的一些资源释放工作


手动抛出异常

  • 使用raise语句手动抛出异常
python 复制代码
>>> raise TypeError('出错了')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 出错了
python 复制代码
>>> raise TypeError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError
python 复制代码
>>> raise Exception('出错了')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception: 出错了

  • 手动抛出的异常必须是在当前环境下已注册 的;若未定义,则报错
python 复制代码
>>> raise MyError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'MyError' is not defined

异常也是常用的程序间通信的方式,类似信号

异常也经常用在测试方面:在对某些驱动进行测试时,我们可以在必要情况下手动抛出异常


自定义异常

在Python中所有的异常都是从BaseException这个根异常类派生

这个根异常类派生如下异常类:

  • SystemExit (系统中断)
  • KeyboardIterrupt (ctrl+c)
  • Exception (内建异常类)

我们考虑的所有内建异常都是继承自Exception 类,可以通过继承Exception类,来实现自定义异常

python 复制代码
class Myerror(Exception):
    pass

def checklist(mylist,index): #这个函数输出对应索引位置上的值
	print (mylist[index])

try:
    mylist = input('请输入一个序列:')
    index = int(input('请输入访问位置:'))
    if index > len(mylist): #如果传入的索引值超过序列最大索引位置
		raise Myerror #raise抛出自定义错误
except Myerror: #捕获自定义错误
	print ('the index is out of range!')
else:
	checklist(mylist,index)
makefile 复制代码
C:\Users\Administrator\Desktop>python 1.py
请输入一个序列:abc
请输入访问位置:4
the index is out of range!

断言

断言一般用来判断一些bool语句,在断言成功时不采取任何措施,否则触发AssertionError(断言错误)的异常:

python 复制代码
>>> assert 1 == 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError
>>> assert not False
>>> #没有抛出断言异常

上下文管理

with是一种上下文管理协议,目的在于从流程图中把 try...exceptfinally关键字和资源分配释放相关代码统统去掉,简化try...except...finlally的处理流程,所以使用with处理的对象必须有enter()exit()这两个方法

  1. with通过enter方法初始化,enter方法在语句体执行之前进入运行
  2. 然后在exit中做善后以及处理异常,exit方法在语句体执行完毕退出后运行

使用场景

with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的清理操作,比如文件使用后自动关闭、线程中锁的自动获取和释放等

python 复制代码
with open('1.txt', 'rb') as fp:
  	fp.read()
相关推荐
hi星尘1 小时前
深度解析:基于Python的微信小程序自动化操作实现
python·微信小程序·自动化
Doker 多克1 小时前
Django 缓存框架
python·缓存·django
miracletiger3 小时前
uv 新的包管理工具总结
linux·人工智能·python
我不会编程5553 小时前
Python Cookbook-6.10 保留对被绑定方法的引用且支持垃圾回收
开发语言·python
ʚɞ 短腿欧尼3 小时前
关系数据的可视化
python·pycharm·可视化·数据可视化·图表
PXM的算法星球6 小时前
【软件工程】面向对象编程(OOP)概念详解
java·python·软件工程
Humbunklung7 小时前
PySide6 GUI 学习笔记——常用类及控件使用方法(常用类矩阵QRectF)
笔记·python·学习·pyqt
蹦蹦跳跳真可爱5897 小时前
Python----深度学习(基于DNN的吃鸡预测)
python·深度学习·dnn
JJ1M88 小时前
Git技巧:Git Hook,自动触发,含实战分享
git·python·自动化
拓端研究室TRL8 小时前
PyMC+AI提示词贝叶斯项目反应IRT理论Rasch分析篮球比赛官方数据:球员能力与位置层级结构研究
大数据·人工智能·python·算法·机器学习