3.9学堂在线python学习笔记 L8 断言与异常
3.9学堂在线python学习笔记
重要笔记
-
我们将学习一些方法以便处理python中出现的错误,即代码不按预期运行或不正常运行
-
Exception将从代码层面处理,从而用户可以知道代码怎么错了,怎么处理它
-
Assertions保证所有输入输出的假设都正确
-
Exceptions错误种类多了去了,类似列表试图访问不存在的索引,类似试图对不合适的变量类型使用不合适的函数,或者更干脆的调用了一个没有提前声明的变量也会出错。
-
还有一种错误是可能混合了不同变量运算:‘字符串乘除法很典型的错误’
-
遇到错误怎么办?
6.1 很坏很坏的主意是根本不改bug,把那个地方用一个赋值给代替了,然后程序能够继续,但是最后的结果都是垃圾
6.2 或者想办法给出一个error信息,但是这很可能很复杂,特别是我们在树当中时不得不一级级将这些设定好的错误值反复传递回去,并且保证不会在各个路过的函数中间产生不必要的额外错误
6.3 更安全的方法是直接停止程序,并且发出“错误信息”
raise Exception("Can't open grade files!")
#这就是一个很好的提出错误信息的方法
try:
#code
except:
raise Exception("ERROR MESSAGES")
遇到错误,直接沿着调用链将错误信息传递到顶层,并且在顶层输出信息即可,但是注意,我也可以使用处理特定异常的处理器
例如,有时候我们想在继续之前清理一些代码,例如
在这个例子中就很好的处理了IO错误,遇到IO错误时直接关掉文件,遇到算数错误时返回错误位置,这让我们的代码变得更精细和耐用,到这里我们已经开始写一些特定类型错误的处理器了,可以写清理代码,也可以传递一些信息.
下面就是我们已经见过的常见错误信息
下面是一个对try,else,finally,exception语句的综合应用
try首先开始尝试执行代码
exception可以编写一个当try错误执行时的处理器
else会当try正确执行时被执行
特别特别需要注意以下这点:
finally无论如何上面的情况(哪怕是break,哪怕上面出了没有设定好的error)都会执行
这是我写的小例子
try:
while True:
print(1)
break
except ZeroDivisionError:
print("ERROR")
else:
print("Successfully executed the code")
finally:
print("Executing the finally clause")
请特别注意,上面的错误处理器的名字ZeroDivisionError不是随便乱起名的,只有python内部识别的特定ERROR类型才可以作为exception的条件,正如下图列出部分
- raise这个命令很有趣,在try代码中如果遇到了finally错误会忽略try的内容,但是finally一旦正常还是要做try
def FancyDivide(list_of_numbers, index):
try:
try:
raise Exception("0")
finally:
denom = list_of_numbers[index]
for i in range(len(list_of_numbers)):
list_of_numbers[i] /= denom
except Exception as e:
print (e)
#请特别注意,没有说明Exception的类型时,无论什么类型都会输出出来!
#但是是默认文字,因为直接输出了e,这里把错误的信息当成e,然后它就能够print了
- 仅仅在raise下面还加一句都不会执行出来
def FancyDivide(list_of_numbers, index):
try:
try:
raise Exception("0")
print('nicely done') #新加
finally:
denom = list_of_numbers[index]
for i in range(len(list_of_numbers)):
list_of_numbers[i] /= denom
except Exception as e:
print (e)
- 如果在任何一个语句中发生异常(exception)并且没有被处理,那么这个异常被暂时保存。 执行’finally’句。 如果存在一个被保存的异常,在’finally’句执行后重新生成。 如果’finally’句引发另一个异常或执行’return’或’break’ 语句,则会将保存的异常丢弃。