7. 模块与异常详解

一、前言

本章主要解决一下前文曾提到的两个东西:模块、异常。

事实上这两个之间并没有什么直接的关联,写在同一章的原因仅仅只是因为只写一个的话,会导致篇幅太短,因为都很简单。

二、异常

我们首先来聊聊异常,这是很多高级语言都拥有的一个特性。

它并非什么高大上的东西,其仅仅只是一种程序错误的处理方式。

较低级的语言不使用它的原因很简单:对程序的性能影响较大,所以一般会更倾向于通过返回值来判断。

但对于像python这种高级语言,那就无所谓了,异常几乎随处可见,与java差不多。

为了更好理解异常,首先我们来看看低级语言是如何处理错误的:

def divi(a, b):
    if b == 0:
        return None
    return a / b


ret = divi(10, 0)
if ret == None:
    print("函数运行出错")
else:
    print(f'10/0={ret}')

就像上面这个函数一样,求两个数相除的结果,而除数b是不能为0的对吧?

所以如果这个函数检测到了b为0,那就可以通过返回None来代表当前函数出现了错误。

None在python中代表一个特殊的“空值”。

这种方法虽然效率较高,但对于我们程序员来说并不友好,你只知道这个函数调用出错了,但你却无法通过返回的None值知道具体错误的原因!

而这时就可以使用异常来替换上面的这种方式,上面的代码改为异常就是下面这样:

def divi(a, b):
    if b == 0:
        raise ValueError('除数不能为0!')
    return a / b

ret = divi(10, 0)

异常也是一个类,称为异常类,这样的类有很多,这里使用的是一个比较简单的ValueError异常类,可以通过raise关键字抛出其后生成的这个异常对象,填入的参数就是我们想要告诉给外面调用者的信息!

这时,一旦调用这个函数,你就会发现下面这样的错误信息:

image-20240309155641429

看起来是不是很眼熟?你写代码的过程中估计也常常会遇到这样的报错信息。

没错,这就是异常!只不过别人写的异常信息是用英文写的,我这里写的中文而已。

也就是说,一旦通过raise 关键字抛出异常了,那程序就会立马报错,并停止运行。

但这很多时候并不是我们想要的,可能我们更希望的是:如果程序出现了错误,那我就先尝试去修复它,如果修复也失败了,程序再终止也不迟对吧?

所以这时候我们就要用到try except语句了:

try:
    ret = divi(10, 0)
except:
    print("出现错误!")

它的用法同样不难,你只需要将你想要正常执行的代码放入try后面的语句块中即可。

如果发生了异常,那就会去跳到后面的except语句块中执行。

注意:如果try语句块中没有出现任何异常,那么后面的except语句块中的代码就不会执行!

这是最简单的用法,并且你会发现,程序现在已经可以正常执行了:

image-20240309155752173

只不过执行的代码为后面的异常块,但至少程序没有直接终止不是吗?

但这样捕获异常太过于宽泛了,虽然我们这里只抛出了一个ValueError异常类,但实际上python中的异常类是相当多的。

为了能够修复异常,我们就得捕获特定的异常,也很简单:

try:
    ret = divi(10, 0)
except ValueError:
    print("出现ValueError异常类错误")
except Exception:
    print("出现其它异常类错误!")

你可以在其后面添加特定的异常类即可,如果try中的语句块出现了对应的异常,那就会去执行该异常块对应的语句。

其中Exception代表了所有的异常类基类,也就是前面的异常没有匹配到,那就都到这个异常块中来。

这是属于类多态的性质,即:父类对象可以接受子类对象,这里就是父类异常可以接受所有它的子类异常类,但由于python是弱类型语言,多态很难体现出来(因为就算没有多态……一个类型的变量也可以轻易改变到另一个类型)

这样就可以修复代码了:

try:
    ret = divi(10, 0)
except ValueError:
    ret=divi(10,1) # 修复,重新调用
except Exception:
    print("出现其它异常类错误!")

如果你还想要知道具体的错误信息,那么还可以使用as关键字:

try:
    ret = divi(10, 0)
except ValueError as err:
    ret = divi(10, 0)
    print(err) # 打印抛出的异常类对象
except Exception as err:
    print(err) # 打印抛出的异常类对象
作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux