00:00
好,接下来我们继续啊,呃,这是我们说的处理异常的一个基本的一个方式啊,这是最简单的,当然它并不是一个我们最终的方式啊,我们接着往下说,往下说什么呢?诶,我们来说一下异常的一个传播,诶,也就是说我们的异常是怎么传的啊,怎么传的,那首先我们来说一下,我们异常的出现无非就是两个位置,一个是出现在像我这种情况是不是出现在我的全局里啊,还有一种情况是不是就出现在什么呀,函数里啊,无非就是两个位置,一个是出现在全局,还有一个就是出现在函数里啊就这么两种可能啊,两种可能,那我们现在来说一下异异常是怎么传播的,呃,这里边呢,我们来看一个看一个例子吧,哎,看一个例子,我直接在这写了啊,先住掉,嗯,在这儿我们来写一个,我直接来一个定义一个函数,我们叫做一个FN啊FN这个函数非常简单,我在这儿就是print的一个,Print的一个什么呢?哎,Print的一个hello,诶FN打印一下这个函数的名,哎,那这个函数我在这是不可以。
01:01
直接去调啊,诶直接来一个FN,我直接一执行hello Fn对吧?哈FN,那好,那现在我来看啊,我现在在这写一个,我在这儿写一个print,一个这个十除以一个零,那现在我这个异常是不是等于出现在全局作用域啊,啊它并不在函数里,所以这个时候我们一执行它的错误就干嘛了,哎就抛了一个对吧,就抛了一个这个trans bag bag什么意思叫做回溯,我们再强调一下叫做于回溯,出现trans back就表示你出现异常了,回溯就是来回溯一下我们这个异常的一些信息,那你会发现这个错误告诉你,诶这这边发现在什么呀,出现在这个13行啊十十三行在我们这个这个他因这个诶module,但是没有写哪个模块,那其实这就表示我们这个主模块,然后这是我们出现一行这个代码,然后这个是不是我们这个异常信息啊,哎,出现了,那这个是现在是在我们全局作与去定义的,那再来看现在我把它干嘛呢?我把它写到我们这个函数里,也就说现在这个异常在函数里,你不调这个函数这个。
02:01
异常是没有的对吧?没有异常的好,那现在我来调一下这函数,我们再执行,再来看这个时候你会发现这个时候干嘛了,这个时候的tra back跟刚才那个明显有区别,刚才那个tra back是不是只有一个信息啊,而当我定义到函数里了哈,FN是函数里了,对吧?然后它的回溯信息是不是有了两个呀?哎,两个你来看这出现出现了一个什么17,诶这第一行上边是19对吧,然后是17 19是哪?19是不是这个位置啊,17是哪,17是不是这个位置啊?哎,那为什么会出现这种情况,那很明显我们异常是不是说首先我们很明显异常是在17行出的,对吧?17行这行代码出现异常,那是不是说我这异常到17行这就停止了,很明显不是,它是不是也导致我们19行这出现异常了,哎出现异常了,那它是怎么回事儿啊,诶怎么回事,那这里边我们来说一下异常当。
03:01
哎,我们在这个函数中,哎出现什么呢?出现我们这个异常时,那注意啊,全局其实也是用啊,全局也是用,我们往下来说,当然在我们这个函数出现函数中出现异常时,如果什么呢?如果在我们的函数中,哎对这个异常进行了处理啊对异常进行了处理,则异常不会再什么呢?诶再向上传播,哎不会再继续传播,也就是说如果你在这儿,咱们现在是不是在FN这里边出现了异常了,如果你在这儿写了这个出了。写了出。这也写了一个这个except except,那这个时候我们来写一个,我随便写一个,我直接pass,我不处理了,不处理了pass,那这个时候这个异常还会不会往外走了,哎,就不会往外走了,外边是不是压根儿就看不见呀?哎外边压根就看不见了,所以这块注意,在函数中出现异常,如果在函数中对异常进行处理,则异常不会再什么呀,继续传播,如果什么呢?如果函数中没有对我们这个异常进行什么呀?哎,进行处理,则异常会继续什么呢?会继续向什么呢?哎,像我们这个外层作用预传播,哎,不是向外层了,会什么呢?会继续向我们这个函数的调用处传播,哎,调用处传播什么意思?现在我们在这儿出现异常了,在第18行这儿出现异常了。
04:36
17行是吧,在17行出现异常了,现在我是不是没有处理啊,没有处理怎么办?没有处理这个异常在这儿没处理,那我就往外传,往外传到哪儿,谁掉的我就传给谁,现在这个函数是不是20行调的呀?好,那我现在这个错误就传给这儿,这儿是哪儿,这儿是不是就全局作用域啊,哎,这是全局作用域,好在这有没有处理,哎,如果没有处理是不是报错了,哎如果没有处理,我这一保存一执行是不是报错了,你会发现这异常的一个传送轨迹,它是从17传到什么,传到20的,那我这儿如果处理了呢,还是那个代码,我直接来一个这个。
05:15
啊踹它这里边有点多是吧,我们不用它吧,直接来一个这个踹啊把这个放到这个TRY里边,还是来写一个这个except except呢,我们这直接来一个这个pass,直接一保存一执行,诶那这个时候。串冒号是一个中文的,保存一下这一执行是不是也没有错,哎,也没有错,所以这儿出异常了,你没处理,没处理怎么办,就传到了什么呀,异常的调用处就是你这个方法函数的调用处传到这儿,这儿如果处理了也没有份儿了,如果这儿也没处理呢?哎,这儿也没处理它是不是继续找那个方法调用处,哎找这函数调用处,那现在看着不明显,咱们这样我改一个,我再写一个D,我们来一个F2 FN2FN2这里边我们写一个print,我来一个哈,一个FN2FN2,然后在FN2里边我来调用FN,在外层我来调用FN2,那这个关系很明显了,我先调在FN2,然后FN2里边是不是调在FN啊,是不是又调它呀,然后是不是在第17项这出错啊,哎17项出错好,那现在我问你,现在17项出错了,我这没处理,传到哪,传到调用处,调用处是不是就是FN2,哎,传到FN2在这儿出错了,这一出错F2这有没有。
06:33
处理还是没有处理,没有处理怎么办?再传,传到FN2调用处是不是到这儿啊?哎,到这儿如果我这个关系更复杂了,我再来一个FN3,这我还是普的一个,普的一个,我们来一个hello fn3,然后呢,我这儿来调的是FN2,在这儿我来调FN3,这个关系比刚才又复杂了,我在全局调到FN3,在FN3里调到FN2,在FN2里调到FN,对吧,那还是这儿出错了,有没有处理,没有处理,没有处理传到调用处是不是FN2啊,FN2这处没处理,没处理传到调用处是不是FN3呀,FN3这有没有处理还是没处理,传到哪了,是不是传到这儿了?哎,传到这儿了,所以这个时候你一看它的传播路径就非常复杂了,先是17行报错,然后是21行,然后是二十五行,然后是27行,那我们来看看十七二十一,二十五二十七,哎,十七二十一,二十五二十七是不是这么一个传播流程,哎传播流程,所以这里边我们来说一下,如果函数。
07:33
没有对异常进行处理,则异常会继续向函数调用处传播,如果如果函数调用处处理了异常啊,处理的异常则什么呢?则不再传播啊,则不再传播,如果什么呢?如果没有处理则什么呢?则继续向我们那个什么呀?哎,调用处传播,哎调用传播,因为总得有人去调你对吧,总得有人去调你啊再继续传播,那是不是以此类推啊?哎,FN没处理传到FN2 FN2没处理传到FN3,那问题来了,那总得有一个头啊,哎,总得有个头啊,如果直到什么呢?直的诶传到哪呢?传递到我们这个全局作用欲,全局作用欲其实就是我们什么呀,我们那个主模块,我们那个闷对吧?哎,主模块我们那个闷。
08:25
哎,主模块直到传到传递到我们全球作用域,如果依然没有处理,诶如果依然没有处理则什么呢?诶则我们这个程序什么呀?诶程序终止啊,程序终止并什么呢?诶并且显示我们这个异常信息啊,异常信息,所以这个时候为什么我们这个异常信息显示了,它是有一个流程的,它是从FN抛到了FN2,又从FN2抛到了FN3,又从FN3是抛到了我们这个全局啊哎,它是一层一层往外传的啊,一层一层往外传的,而赶巧了我们每一个位置都没有对异常进行处理,每一个位置都没有对异常进行处理,那这个时候干嘛了,我们程序就只能什么,就只能去终止了啊,只能终止了,所以你会发现这个PE为什么叫追溯,你会发现它是不是发现了一个异常的流程啊,诶,所以当你去看到这个异常的出现的时候,你要定义那个异常到。
09:25
根儿的问题在哪儿,根儿的问题在哪儿,你只看谁呀,最后一个你就知道了,肯定是17行,这是引起异常那个什么呀,原因肯定是这行代码出问题了,其他的是不是都是因为它的问题去导致的呀,诶导致了,而正好我没有一个地方去处处理这个异常,所以就导致什么了,诶导致这出错了啊导致出错了,所以这个流程你要搞清楚,它是一个一层一层向外传递的,所以我们说了这个异常我们也叫什么呀,哎,我们也叫抛异常。诶,叫做抛出异常啊,抛出异常什么叫抛出啊,我这儿没处理,咔,往上抛,上面还没处理,往上面上面抛还没处理,往上面上面抛,直到找到处理的为止,都没处理哦,OK,那咱们就报错,呃,报错所以叫抛异常啊,叫抛异常,因为它是往上往上抛的,懂这意思吧,哎,抛异常,所以这个时候我们就看到这个异常信息啊,Trans back,追溯这个异常的信息,那这里边我们就会产生一个疑问,诶,抛异常啊,抛异常。
10:25
抛的是什么呀?你说是抛异常了,抛异常传播,异常传播,异常传播的是什么呀?对吧,你说我传给你一个球,我传给你一个东西,我传给你一个手机传一,这传一,那我是不是得给你传一个东西,好,那现在你说了,我在FN这出现一个错误,我抛给了FN2 FN2出个错误抛给FN3 FN3出错误抛了我们全区作用域,他抛的是啥呀?对吧,你得懂有的一个东西给抛啊,对吧,那抛的是什么呢?那这里边我们注意了,我们来说一下,哎。
11:06
抛的到底是什么东西啊,我们来说一下我们这个,当我们这个程序运行过程中,诶出现这个异常以后,我们的所有的这个异常信息,诶异常信息会什么呢?诶会被诶保存到一个专门的什么呢?异常这个对象中啊,会保存到一个专门的异常对象中,而什么呢?而我们这个异常传播时,传播时实际上哎就是将我们这个异常对象,哎将我们这个异常对象抛给了什么呢?诶抛给了我们这个调用处啊调用处所以注意我们的所有异常信息都是保存到专门的异常对象中的啊,都是包存到异常对象中的,所以在这儿我们说的传传传抛抛抛抛的是什么?抛的就是那个异常对象啊,抛的是这个异。
12:07
异常对象,那这个每一个异常都有它专门的对象,比如说在这儿我们来看,我们这儿是不是有一个叫做zero dev一个error啊,这个实际上就是一个什么呀,哎,就是一个类啊,比如。比如我们这个,哎你看它前边首字母是不是大写呀,哎你看它这个首字母大写,你要知道它实际上就是一个什么呀类,用的是我们这个大驼峰民法这个就是一个呀类啊这个类的对象,诶专门用来干嘛呢?哎用来表示我们这个什么呀,哎表示我们这个除零的一个异常啊除灵的异常,我们还见过什么呀,我们还是不是还见过这玩意儿啊,我们来看一下,我这直接来一个哎润,我们来一个这个A打印变量A,这A是没有啊,我们这一执行,咱们来看这是不是出现一个name error,哎,Name error name error这个类,哎它的这个对象,哎专门用来干嘛呀?哎用来处理我们这什么呀?哎处理这个哎变量错误的异常啊,错误的异常,那这些等等等等吧,诶,每一个类都会有它专门,每一个异常都会有它专门的一个类,那注意了,这玩意儿都是什么,都是类,当出现错误以后。
13:21
当出现除零的错误以后,它会创建一个zero error这个类的实例啊,实例,当出现name error以后,它会创建一个name error的一个实例,所以现在这个东西,你看前边这个东西都是什么,都是类,我们可以打印一下看看啊,我在这打印吧,直接打印一个,我们来一个什么呀,哎,来一个name error啊,一保存我们这一执行,咱们来看在这儿是不是一个class呀,哎,Class它就是一个什么呀,哎,就是一个类,那在我们的什么呢?在我们的Python中。哎,在我们这个Python中,为我们什么呢?为我们的提供了哎,多个我们这种异常对象啊,给我们的提供了多个异常对象,很多很多是吧,我们来看看在哪还是找到文档,文档找谁呢?找我们这个library reference啊,库的一个描述直接点进来,在这儿我们会有一个叫做build in exceptions exceptions就是异常啊,异常直接点开它,它这里边会告诉我们给我们提供了多少种异常,对吧,太多了。
14:26
是不是太多了,哎,太多了,我们看几个啊,我们简单过,简单看一眼,我们就不全看了,哎,我们找找有什么,我们,诶有有没有我们熟悉的,你看这index error啊,Index error是不是我们这个索引错误呀,哎,索引错误哎然后再来看我们这个key error key error什么时候出呀?哎,你在用字典的时候,你用那个key字典里边没有是不是就是key error,哎,Key error name error是我们这个变量那个错误呀,哎,变量没有,没有赋值,没有赋过值报这个错,然后下边还有很多很多一系列的错误,我们就不,哎不再去展示了是吧?不再去展示了,这是什么呀,语法的错误,这应该是我们这个缩进的错误是吧?等等等等,会有一系列type类型的一个错误,它会给我们提供一系列的一个什么呀,哎,一系的一个错误信息啊,错误信息好,那同学这时候就会说了,哎,老师你说他异常传播的时候,他抛的是一个对象对吧?哎,抛的是一个对象,除这个除零的。
15:26
这时候抛的是我们这个异常的实例对吧?这个类的实例出现这个变量错误的时候,抛的是这个类的实例,对吧?哎,那这个实例我能不能看见呀,我能不能看见呀?哎,那这一块我们怎么去看到这个异常的信息,那这个我们在这里先停一下,待会我们来讲怎么来捕获到他抛出的那个异常的对象,并且通过这个对象来看到这什么呀?诶这个信息啊,这里我们先停一下。
我来说两句