异常处理
一、错误的分类
语法错误:因语法没有通过python解释器于法检测
逻辑错误:有时不能避免
什么是异常
异常就是python程序运行时因发生错误而终止。在python的异常报错信息中包含:错误信息追踪信息;错误类型;错误值
异常种类
常见异常
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) 代码没有正确对齐
IndexError 下标索引超出序列边界,
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
更多类型
ArithmeticError
AssertionError
AttributeError
BaseException
BufferError
BytesWarning
DeprecationWarning
EnvironmentError
EOFError
Exception
FloatingPointError
FutureWarning
GeneratorExit
ImportError
ImportWarning
IndentationError
IndexError
IOError
KeyboardInterrupt
KeyError
LookupError
MemoryError
NameError
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
ReferenceError
RuntimeError
RuntimeWarning
StandardError
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
ZeroDivisionError
二、异常处理
因为异常发生之后,异常之后的代码就不再运行。异常处理就是捕捉发生的错误,防止程序崩溃,并进行程序分流。
异常除了python解释器检测到的之外,我们还可以主动抛出异常。
python解析器去执行程序,检测到了一个错误时,触发异常,异常触发后且没被处理的情况下,程序就在当前异常处终止,后面的代码不会运行,严重影响使用体验,这时我们需要对这些异常进行处理,让程序能够顺利执行下去,提高程序的健壮性和容错性。
如何处理
使用 if 判断
最基本的使用 if else 进行简单异常的处理分流
存在局限性:if判断式的异常处理只能针对某一段代码,对于不同的代码段的相同类型的错误需要写重复的if来进行处理;大量与异常处理有关的if语句,会使得代码可读性极变差。
使用try
基本语法
try:
被检测的代码块
except 异常类型:
try中一旦检测到异常,就执行这个位置的逻辑
示例:
s1 = 'hello'
try:
int(s1)
except ValueError as e: #只能处理已知类型错误
print(e)
多分支
s1 = 'hello'
try:
print(s1[50])
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
万能异常Exception
s1 = 'hello'
try:
int(s1)
except Exception as e:
print(e)
- 如果是只是单纯的想解决异常,统一可以抛弃这些错误,使用exception处理即可;
- 如果是分异常处理或者需要给用户错误提示时,选择多分支,如下:
dic = {1:111,2:222,3:333}
while 1:
try :
num = input('请输入1~3好选项:').strip()
a = int(num)
print(dic[a])
except KeyError as e :
print('选项超范围')
except ValueError as e:
print('请输入数字')
- 如果只针对某几个错误提示,其他异常不需要提示,可以在多分支之后加上万能异常处理,如下;
s1 = 'hello'
try:
int(s1)
except IndexError as e: #只是针对下标超范围的错误提示给用户
print(e)
except Exception as e:
print(e)
固定搭配
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
else:
print('try内代码块没有异常则执行我')
finally:
print('无论异常与否,都会执行该模块,通常是进行清理工作')
else: 如果try之后没有发生异常,可以在异常处理的下面,加上一个else,继续执行else里的代码,可用作分流用,使用else必须要有except;
-
finally: 不管异常是否发生,都会执行;而且是在异常发生之后整个程序终止之前执行finally里的代码,使用finally前不一定要有except;
finally的应用场景:文件操作,关闭文件句柄;连接数据库时,关闭数据库引擎;在函数内,return结束函数之前,执行finally的语句
主动抛出异常
自己定义错误提示
try:
raise TypeError('类型错误')
except Exception as e:
print(e)
断言 assert
主动抛错的一种形式,语法:assert 条件,这里的条件可以是函数的返回值或是其他条件,是根据需求改变的
assert 1 == 1
print('111')
assert 1 == True
print('2222')
自定义异常 BaseException
BaseException所有异常继承的基类
class Connection(BaseException):
def __init__(self,msg):
self.msg=msg
def __str__(self):
return self.msg
try:
raise Connection('连接异常')
except Connection as e:
print(e)
优势
在没有牺牲程序刻度想、健壮性和容错性的前提下,使用try ... except异常处理可以代替if
- 把错误处理和真正的工作分开来
- 代码更易组织,更清晰,复杂的工作任务更容易实现;
- 更安全,程序不至于因一些小的疏忽而意外崩溃;
什么时候用
异常处理不能经常使用,异常处理是需要耗费性能的;有些错误是需要分流使用的;代码的可读性变差。
异常要在关键节点使用。