By Jackson@ML
每一个程序都未必是健壮的,有时候很脆弱。只有在人的理想思维状况下,返回的结果才是正确的,如意的。
面对种种编写有疏漏的程序,常常会出现错误,下面举出不同的例子,来看会出现哪些问题。
1) 例如,print()语句执行时,缺少了括号,如下代码:
print "Hello, world!"
File "" , line 1
print "Hello, world!"
^^^^^^^^^^^^^^^^^^^^^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?
提示Syntax Error(即:语法错误)。
通过以下的例子,可以看到其它异常。除数等于零时,被除数除以它就会报错。
x = 5 / 0
Traceback (most recent call last):
File "" , line 1, in <module>
ZeroDivisionError: division by zero
还有一个例子:
lst = [1, 2, 3]
print(lst[3])
Traceback (most recent call last):
File "" , line 1, in <module>
IndexError: list index out of range
仍有一个例子:
d = {'a': 'hello'}
d['b']
Traceback (most recent call last):
File "" , line 1, in <module>
KeyError: 'b'
提示KeyError,即字典对象的键 ‘b’不存在,导致异常。
我们注意到相关异常的名字都有个共同点,即以Error结尾。在Python编程语言中,error和exception几乎是可以交换使用的。但是,往往错误比异常更加严重。
前述相关的例子中所有的错误类都继承自Exception。
有了异常,就需要着手处理。做项目过程中,实际探究一下Python程序需要通知用户或调用输入不合法的函数,那该如何处理?
先来看以下这个类,用来添加偶数到列表中。
class EvenOnly (list):
def append(self, integer):
if not isinstance (integer, int):
raise TypeError ("Only integers can be added to lists")
if integer % 2:
raise ValueError ("Only even numbers can be added to lists")
super().append(integer)
e = EvenOnly()
e.append("a string")
在Visual Studio Code中执行,结果如下图所示:
出现TypeError类型错误!,意思是只有整数能够添加,而字符串“a string”违背了这一原则,因此报错。
修改最后一个语句为:
e.append(3)
这次出现了不一样的报错,即ValueError,属于数值错误,提示仅有偶数可以被添加;由于整数3是奇数,并不是偶数,因此报错。
像上述的例子,都属于程序抛出了异常,看起来似乎立即停止了程序运行。这是正常的流程,即抛出异常后,所有代码都不会继续被执行,而是停止,除非处理了异常。
接下来,看一个无返回值的函数,按照这个逻辑来写这个函数,其中,使用Raise抛出一个明确的异常(提醒用户发生了什么):
def novalue_return():
print("I am going to raise an exception")
raise Exception("Raised Exception!")
print("This will never execute.")
return "No value returned."
novalue_return()
执行结果如下图所示:
这次,抛出了程序设定的异常,即Exception: Raised Exception! 尽管看起来不是特别详尽,但是这个异常可以自己随意设定。
如果了解到程序有可能抛出最接近的类别的异常,那么输出的异常字符串就能更好更精确地指导程序完善过程,使得代码精进成为可能。
异常发现了,也能够自行设定抛出了。那么,当遇到一个异常情况,代码应该如何应对或者从中恢复呢?我们需要恰当的异常处理方法。
使用 try…except 语句块包裹可能抛出的异常的代码,就是不错的选择。修改上述代码如下操作:
def novalue_return():
print("I am going to raise an exception")
raise Exception("Raised Exception!")
print("This will never execute.")
return "No value returned."
try:
novalue_return()
except:
print("An exception was caught!")
print("This will be executed after the exception")
可以看到,在原本需要直接执行的novalue_return()语句,被try … except块包裹,完成后再打印一个语句说明在异常之后执行。
执行该程序如下图所示:
显而易见,在程序执行中,按照我设定的步骤,由于发生了异常,则执行except块,打印输出An exception was caught!(一个异常被捕获);最后,打印常规语句,说明在异常之后执行。
一旦捕获异常,那么就能够进行代码的善后清理,并且继续执行代码,而不受异常函数的影响。
抛出异常后,novalue_return()函数的剩余代码仍然不会执行,但是调用这个函数的代码能够恢复,并且继续执行。
本文简述了异常的基本机制,异常的出现,如何抛出以及处理异常。感谢您的阅读。
技术好文陆续推出,敬请关注。
喜欢就点赞哈!您的认可,我的动力。