4 异常
4.1 异常和错误
异常和错误都能引起程序执行错误而退出,它们属于程序没有考虑到的例外情况,但两种有很大区别:
- 异常:可以预见的例外情况。如除数为0、类型不对、打开的文件不存在 —— 可以预见
- 错误:编码逻辑产生的不可预见的情况。如列表只有6个元素,程序去索引第7个 —— 不可预见
4.2 异常解读
解读异常提示信息,能帮助快速发现问题和定位出错代码位置,下面是一个异常解读演示。其中最重要的是「异常类型」,它表明异常发生原因,也是处理异常的依据。
4.3 常见异常
python中异常有很多种,经常会遇到的除invalid syntax(无效语法)外,只需掌握如下几种即可。
异常类型 | 注释 |
---|---|
SyntaxError | 语法错误 |
NameError | 访问变量未声明 |
ZeroDivisionError | 除数为 0 |
ValueError | 传入参数无效 |
TypeError | 类型错误(对类型的操作无效) |
AttributeError | 对象没有这个属性 |
IndexError | 序列中没有此索引 |
KeyError | 映射中没有这个键 |
IndentationError | 缩进错误 |
4.4 异常捕获和处理
可以使用try-except
语句,来捕获处理python中出现的异常,其使用语法如下:
程序优先执行try子句,若无异常则忽略except子句直接结束;若产生异常且与except设置的异常名称一致,则执行except子句;若有多层嵌套且异常与任何的excep都不匹配,则异常将会传递给上层的 try 。
注意:
- 一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常,但最多只有一个分支会被执行
- 一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组
- try-except捕获处理机制不能滥用,否则代码可读性会降低
常见的有这几种应用场景:用户输入合规性、打开文件是否成功、爬虫向服务器发起请求。
# 异常处理机制
try:
num = eval(input("请输入一个数字:"))
print(num*2)
except NameError: # 指定异常类型为NameError
print("输入错误,请输入一个数字!")
except: # 没指定任何类型,表示对应的语句块可以处理所有其他异常
print("其他错误")
若想要程序一直执行,直到满足条件为止,可以巧用死循环 + 异常。
# 若想要一直执行,直到满足条件为止:用死循环
while 1:
try:
num = eval(input("请输入一个数字:"))
print(num*2)
break # 跳出死循环
except NameError: # 指定异常类型为NameError
print("输入错误,请输入一个数字!")
except: # 没指定任何类型,表示对应的语句块可以处理所有其他异常
print("其他错误")
更多可参看:https://www.runoob.com/python3/python3-errors-execptions.html
4.5 else拓展
try-except
语句还有一个可选的else子句,如果使用这个子句,那么必须放在所有的except子句之后。
和for循环、while循环中的else一样,try-except
中的else子句将在try子句没有发生任何异常时才执行。
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except IOError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()