异常捕获
- 什么是异常?
异常Exception:代码写错了,解释器无法运行。主要包括 书写上语法上的错误和运行时产生的错误。
从轻到重: 拼写检查inspection< 普通information < 警告warning < 运行时错误 runtime Error < 异常Exception < 严重的错误Error 崩溃
- 错误栈
错误跟踪栈 traceback:错误栈展示出错信息: 哪一个文件、第几行、出错代码在哪个模块方法下、出错的代码。根据函数的嵌套和调用执行顺序,按从早到晚排序。最后是出错类型和描述。
如何排错:看看错误栈的前面的信息,知道从哪个代码开始出错;看看后面的信息,知道哪一句代码出错了;看看最后一句错误类型和描述。
如下面会出错的代码:
def foo():
print(1/0)
def boo():
print('hello')
foo()
boo()
- 常见的错误类型
1)变量未声明就调用 print(a) NameError: name ‘a’ is not defined
2)语法错误。少写冒号等。 SyntaxError: invalid syntax
3)缩进错误。 IndentationError: expected an indented block
4)索引错误。 [1,2,3][3] 。 IndexError: list index out of range
5)类型错误。调用函数时参数的类型或个数不匹配。 TypeError: boo() takes 0 positional arguments but 1 was given
6) 值错误。 int(‘h’) ValueError: invalid literal for int() with base 10: ‘h’
7)零除错误。 1/0 。 ZeroDivisionError: division by zero
8)递归错误。 RecursionError: maximum recursion depth exceeded
9)键错误 {‘key’: ‘value’}[‘aaa’] KeyError: 'aaa
…
捕获异常
(重点)捕获异常: try … except … finally
try 括住可能发生问题的一些语句。偷懒方法try括住程序最外层,但这样捕获后不好定位出错地方。
except 后面跟异常的类名,如果捕获到这种异常,那么就会执行语句块,执行发生异常后的一些处理,处理比如 用户提示信息、记录日志、业务逻辑。
finally 不管程序正常运行,或是出现某种异常被捕获,再或是出现异常没有被捕获,最终都会一定执行finally语句块的内容。
捕获异常应该适当使用,使用过多代码会乱,不用的话错误可能导致程序崩溃带来损失。场景:捕获数据库操作代码。
def foo():
try:
print(1/0)
print('hello')
except ZeroDivisionError:
print('不能除以0')
finally:
print('我最后执行')
print('world')
def boo():
print('hello')
foo()
print('world')
boo()
场景:一个大型项目,业务逻辑复杂。当出现异常错误时,我们并不希望程序终止,希望程序主体功能运行;收集分析错误信息。
try语句块里面的变量变成局部变量,注意外部不要引用内部局部变量。
如果try块中的代码可能报多种异常,那么多写几个并列的except语句。
不知道错误类的类名;可能会出现代码中定义错误之外的未知新错误。使用所有错误类的父类Exception类来捕获。
finally场景:打开文件资源,不管有没有出错,最终应该保证关闭文件。
as: 把…作为… 。类似等号赋值,代码可以写成一行。
try:
file = open('demo.txt')
content = file.read()
print(content)
except FileNotFoundError:
print('文件未找到,请检查文件名')
except UnicodeDecodeError:
print('unicode解码错误')
except Exception as e: # e = FileNotFoundError()
print(e)
finally:
file.close()