Python从零开始学 Day06~异常处理
本文是上一篇文章的后续,详情点击该链接
在我们实际工作中,我们遇到的情况,并不会那么完美。假如我们写了个计算器,用户偏偏输入 2 / 0 这样的式子,计算机底层是肯定报错的。但是,这样的报错又不能让客户看见。怎么办呢?这个时候我们就需要异常处理机制来解决
比如说下述代码,我们有了异常处理,就不会让客户看到异常
try:
a = int(input("请输入式子"))
print(a)
except:
print('输入错误!')
异常类的继承层次
python中一切都是对象,异常也采用对象的方式来处理。处理过程:
抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给解释器。
捕获异常:解释器得到该异常后,寻找相应的代码来处理该异常。
try...一个 except 结构
try:
a = int(input("请输入式子"))
print(a)
except BaseException:
print('输入错误!')
try...多个 except 结构
try:
a = 5/0
print(a)
except ZeroDivisionError:
print("除数不能为0");
except TypeError:
print("除数和被除数都应该为数值类型")
except NameError:
print("变量不存在")
try...except...else 结构
try...except...else 结构增加了“else 块”。如果 try 块中没有抛出异常,则执行 else 块。如果 try 块中抛出异常,则执行 except 块,不执行 else 块。
try:
a = 5/3
except ZeroDivisionError:
print("除数不能为0");
except TypeError:
print("除数和被除数都应该为数值类型")
except NameError:
print("变量不存在")
else:
print("a = " , a)
try…except…finally 结构
try...except...finally 结构中,finally 块无论是否发生异常都会被执行;通常用来释放 try 块中 申请的资源。
try:
a = 5/0
except BaseException:
print('我是异常')
else:
print("a = " , a)
finally:
print("即使报了异常我也执行")
return 有两种作用:结束方法运行、返回值。我们一般不把 return 放到异常处理结构 中,而是放到方法最后。
常见异常汇总
BaseException | 所有异常的基类 |
Exception | 常规错误的基类 |
ArithmeticError | 所有数值计算错误的基类 |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
ImportError | 导入模块/对象失败 |
IndentationError | 缩进错误 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
OSError | 操作系统错误 |
OverflowError | 数值运算超出最大限制 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
StandardError | 所有的内建标准异常的基类 |
StopIteration | 迭代器没有更多的值 |
SystemExit | 解释器请求退出 |
TabError | Tab 和空格混用 |
TypeError | 对类型无效的操作 |
UnboundLocalError | 访问未初始化的本地变量 |
UnicodeDecodeError | Unicode 解码时的错误 |
EnvironmentError | 操作系统错误的基类 |
EOFError | 没有内建输入,到达 EOF 标记 |
UnicodeEncodeError | Unicode 编码时错误 |
DeprecationWarning | 关于被弃用的特征的警告 |
UnicodeError | Unicode 相关的错误 |
UnicodeTranslateError | Unicode 转换时错误 |
UserWarning | 用户代码生成的警告 |
ValueError | 传入无效的参数 |
Warning | 警告的基类 |
WindowsError | 系统调用失败 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
FloatingPointError | 浮点计算错误 |
SystemError | 一般的解释器系统错误 |
FutureWarning | 关于构造将来语义会有改变的警告 |
LookupError | 无效数据查询的基类 |
SyntaxWarning | 可疑的语法的警告 |
SyntaxError | Python 语法错误 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
RuntimeError | 一般的运行时错误 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
NotImplementedError | 尚未实现的方法 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
NameError | 未声明/初始化对象 (没有属性) |
MemoryError | 内存溢出错误(对于 Python 解释器不是致命的) |
IOError | 输入/输出操作失败 |
with 上下文管理
finally 块由于是否发生异常都会执行,通常我们放释放资源的代码。其实,我们可以通 过 with 上下文管理,更方便的实现释放资源的操作。
with 上下文管理可以自动管理资源,在 with 代码块执行完毕后自动还原进入该代码之前的现场或上下文。不论何种原因跳出 with 块,不论是否有异常,总能保证资源正常释放。极大的简化了工作,在文件操作、网络通信相关的场合非常常用。
with open("d:/alvin.txt") as f:
for line in f:
print(line)
自定义异常
程序开发中,有时候我们也需要自己定义异常类。自定义异常类一般都是运行时异常,通常 继承 Exception 或其子类即可。命名一般以 Error、Exception 为后缀。
自定义异常由 raise 语句主动抛出
class AgeError(Exception): #继承Exception
def __init__(self,errorInfo):
Exception.__init__(self)
self.errorInfo = errorInfo
def __str__(self):
return "年龄错误!"
if __name__ == "__main__":
age = 200
if age < 1 or age > 120:
raise AgeError(age) #这里是raise不是return
else:
print("正常的年龄",age)