异常
1.什么是异常
【异常在python中是一个对象】
异常简单理解,就是非正常,没有达到预期目标。
异常是一个事件,并且这个异常事件在我们程序员的运行过程中出现,会影响我们程序正常执行。
异常分两种:
-
语法错误导致的异常
-
逻辑错误导致的异常
#在程序无法正常运行处理时,就会出现一个异常,在python中异常是一个对象,表示一个错误。
#例如:获取一个不存在的索引
a = [1,2,3]
print(a[5])
>>>Traceback (most recent call last):
File "D:/学习笔记/新职课/第五章-模块,包与库训练/第六节/test.py", line 2, in <module>
print(a[5])
IndexError: list index out of range
#IndexError:异常类
#list index out of range 异常信息
#不同的异常有不同的类
2.如何处理异常
-
如果错误发生的情况是可以预知的,那么就可以使用流程控制进行预防处理
a,b = 2, '3' res = a + b print(res) #此时会报异常,类为TypeError #此时错误的发生条件是可以预知的,因为如果要做+运算,要保证a和b可以相加 a,b = 2, '3' if isinstance(b,int): print(a+b) #通过流程控制进行预防处理
-
如果错误的发生条件不可预知,就可以使用 try: … except: … 在错误发生时进行处理
语法: try: 可能发生异常错误的代码 except: 如果发生异常则进入 except 代码块进行处理
''' 假设读取的文件不存在,会发生错误,可以使用两种方式进行处理, 1. 可以在文件读取前先判断当前的文件是否存在 2. 也可以使用try: ... except: ... 在错误发生时进行处理 注意:try: ... excep: ... 是在错误发生后进行的处理。和if有着根本性的区别。 if是避免了错误的发生, try: ... excep: ...是错误确实发生了,但是程序还可以继续运行 '''
3.try: … except: … 详细用法
-
使用try: … except: … 处理指定的异常。如果引发了非指定的异常,则无法处理
try: s1 = 'hello' int(s1) # 会引发 ValueError except ValueError as e: # except IndexError as e: #如果引发了非指定的异常,则无法处理 print(e) >>>invalid literal for int() with base 10: 'hello'
-
多分支处理异常类:不同的异常会走向不同的except处理
s1 = 'hello' try: # int(s1) # ValueError s1[5] # IndexError except IndexError as e: print('IndexError',e) except KeyError as e: print('KeyError',e) except ValueError as e: print('ValueError',e) >>>IndexError string index out of range
-
通用异常类 Exception,在没有指定的情况下所有的通用异常类都会指向Exception
s1 = 'world' try: int(s1) except Exception as e: print('Exception ===',e) >>>Exception === invalid literal for int() with base 10: 'world' #如果触发了指定的异常类,则会指向指定的异常类 #如果触发的不是指定的异常类,则会指向Exception
-
多分支异常类+通用异常类,这样引发异常后会按照从上往下的顺序去执行对应的异常处理类;
【注意是从上往下的顺序!如果Exception写在最上面,则触发的是Exception类】
s1 = 'hello' try: # int(s1) # ValueError s1[5] # IndexError except IndexError as e: print('IndexError',e) except KeyError as e: print('KeyError',e) except ValueError as e: print('ValueError',e) except Exception as e: print('Exception',e)
-
try: … except: … else: …
s1 = 'hello' try: str(s1) except IndexError as e: print('IndexError',e) except ValueError as e: print('ValueError',e) except Exception as e: print('Exception',e) else: print('try代码块中没有引发异常时,执行') >>>try代码块中没有引发异常时,执行 #这里和把else里的print放到try里是一样的 s1 = 'hello' try: str(s1) print('try代码块中没有引发异常时,执行') except IndexError as e: print('IndexError',e) except ValueError as e: print('ValueError',e) except Exception as e: print('Exception',e) >>>try代码块中没有引发异常时,执行
-
try: … except: … else: … finally:
【finally 无论是否引发异常,都会执行。通常情况下用于执行一些清理工作。】
s1 = 'hello' try: int(s1) print('如果前面的代码引发了异常,这个代码块将不在继续执行。。') except IndexError as e: print('IndexError',e) except ValueError as e: print('ValueError',e) except Exception as e: print('Exception',e) else: print('try代码块中没有引发异常时,执行') finally: print('无论是否引发了异常,都会执行这个代码块') print('如果上面的代码有异常并且进行了处理,那么后面的代码将继续执行') >>>ValueError invalid literal for int() with base 10: 'hello' 无论是否引发了异常,都会执行这个代码块 如果上面的代码有异常并且进行了处理,那么后面的代码将继续执行
-
使用 raise ,主动抛出异常
try: #可以使用 raise 主动抛出异常,并设置异常信息 raise Exception('发生错误') except Exception as e: print('啊,Exception',e) >>>啊,Exception 发生错误
-
assert 断言
assert 1 == 1 # 如果后面的表达式正确,则什么也不做 assert 2 == 1 # 若表达式错误,则直接抛出AssertionError >>>Traceback (most recent call last): File "D:/学习笔记/新职课/第五章-模块,包与库训练/第六节/test.py", line 2, in <module> assert 2 == 1 # 若表达式错误,则直接抛出AssertionError AssertionError
4.自定义异常处理类
当异常出现时,对异常信息进行写入日志。
#自定义异常处理类
'''
在出现异常后,对异常进行处理。并且把异常信息写入日志
日志的基本格式:
日期时间 异常的级别
异常信息:引发的异常类,异常的信息,文件及行号
'''
###4.1 traceback 回溯模块 https://docs.python.org/3.7/library/traceback.html
# 通过 traceback 模块获取异常信息
import traceback
try:
int('aa')
except:
a = traceback.format_exc() #这个函数就是显示错误信息的
print(a)
print('此时程序还可以继续往下运行')
>>>Traceback (most recent call last):
File "D:/学习笔记/新职课/第五章-模块,包与库训练/第六节/test.py", line 3, in <module>
int('aa')
ValueError: invalid literal for int() with base 10: 'aa'
此时程序还可以继续往下运行
###4.2 logging 日志模块 https://docs.python.org/3.7/library/logging.html
# 自定义异常日志处理类
class Myexception():
def __init__(self):
import traceback
import logging
# logging的基本配置
logging.basicConfig(
filename='./error.log',# 日志存储的文件及目录
format='%(asctime)s %(levelname)s \n %(message)s',# 格式化存储的日志格式
datefmt='%Y-%m-%d %H:%M:%S'
)
# 写入日志
logging.error(traceback.format_exc())
# 使用自定义异常处理类
try:
int('bb')
except:
print('在此处进行异常的处理')
Myexception() # 在异常处理的代码块中去调用自定义异常类
##5.标准的异常类
异常名称 | 描述 |
---|---|
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSError | 操作系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
NameError | 未声明/初始化对象 (没有属性) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |