python学习笔记-tip45(异常处理机制--错误处理)

引言

我们用什么语言写项目,其实都会出错,错误有很多种,有我们写的代码本身就有问题,这个时候属于编译错误,有的代码运行的时候有问题,这个属于运行时异常,python其实也有一套自己的异常处理机制。今天我们来学习一下。

解决错误中的一种方式:返回错误码

返回错误码其实是程序员排除错误的一种方式,他们往往会有一个错误码的字典,字典里面记录了什么数字对应着什么错误;然后当程序返回什么码的时候,去再对照之前那个字典,就能够知道什么错误了。
但是错误码其实有一个局限性,就是当我们返回的结果如果和错误码混合在一起,那么久不太好区分了。

为了避免这种问题,我们常用try catch finally(java语言中)等方式进行运行时异常的捕获。
当然python也有类似的。

try...except...finally

我们先试用一下

    try:
        print('try...')
        r=10/0
        print('result:',r)
    except ZeroDivisionError as e:
        print('except:',e)
    finally:
        print('finally...')
    print('END')

大家应该能看懂大概意思,我们来看下实际输出结果

当我们认为某些代码可能会出错时,就可以用try来运行这段代码
如果执行出错,则后续代码不会继续执行,而是直接跳转至except语句块
执行完except后,如果有finally语句块,则执行finally语句块
至此,执行完毕

ok,当然,如果没有错误出现,那么也不会执行except代码块,如下如


(注意:如果想得到整数,那么用"//")

从上面的输出结果,可以看到,不论异常有没有finally一直都会执行,就像java中的一样

那么,如果发生了不同种的错误,是不是可以使用多种except去处理呢?

答案是肯定的!
我们直接来看示例



这个例子中,我们用一个 except 来捕获 ValueError ,一个 except 来捕获 ZeroDivisionError

此外,如果没有错误发生的话,还可以在 except 后添加一个 else: 去执行没有该错误的处理

如下面例子所示


需要注意的是,并不是一个 except 对应一个 else ,而是当所有的 except 都没处理的话,才会执行唯一的 else ,下面的写法是错的

错误写法

Python的错误也是类,所以如果想捕获某一大类的错误,直接捕获大类就好了

所有的错误类,都继承自 BaseException类

常见的错误类型和继承关系看这里:
https://docs.python.org/3/library/exceptions.html#exception-hierarchy

使用try...except捕获错误还有一个巨大的好处,就是可以跨越多层调用

请看下方示例:

由此我们发现,有了这个跨越多层调用 except ,大大减少了复杂的 try except finally 代码的使用

调用栈

如果出的错没有处理,那么最终会被 python 解释器捕获,打印一个错误信息,然后程序退出
我们来演示一下


出错的时候,一定要分析错误的调用栈信息,才能定位错误的位置

出了错之后要懂得找打错误的位置,上面的例子错误的位置就在第三行,10/s的位置,找到错误的位置,确定错误的类型,我们就能够解决了

logging类

我们从上面的例子知道了,即使我们不进行异常的捕获,python编译器也会对异常进行处理,我们也能定位到异常的位置,那么还要异常处理干什么?

其实不然,python处理器虽然会处理异常,但是在处理的同时,也将程序终止。
其实我们可以借助logging类去处理,logging类既会想python处理器一样将错误展示出来,也不会终止程序,如下例所示


抛出错误

需要明确的是:
错误是一个 class ,我们捕获的错误其实就是捕获了该 class 的一个实例
所以说,错误并不是凭空出现的,而是有意抛出的

python内置的函数会抛出很多类型的错误,当然我们自己编写的函数也可以抛出错误。
如果要抛出错误,我们可以根据需要,可以定义一个表示错误的 class ,然后选择好继承关系,
最后用 raise 语句抛出一个错误的实例。

比如,现在定义一个错误,让他继承ValueError

  class FooError(ValueError):
            pass

然后在适当的地方抛出

  def  foo(s):
         if s==0:
            raise FooError('Foo Error %s' %s)
         return 10/s

这样,当我们调用foo函数时,如果我们传入
0
那么将会抛出FooError的错误,并且打印
“Foo Error 0”
否则的话,则会直接返回 10/s 的返回值
我们来看一下真实的案例演示:



但是,我们只有在必要的时候才会定义我们自己的错误类型,在定义错误类型时,一定要继承对父类,否则会造成麻烦

下面再来看另外一中处理错误的方式:重复抛出错误

由上图,我们可以看出,虽然已经捕获了异常:打印出了FooError!
但是又将之前的异常抛出,这是什么操作呢?

这个操作有的时候很有必要

有的情况下,由于当前函数不知道怎样去处理当前遇到的错误,那么最恰当的方式是往上抛,让顶层调用者去处理。就好比像一个员工遇到了一个棘手的问题不知道怎么处理,那么他最恰当的做法是交给他的上司,如果他的上司也处理不好,那么就会一直往上抛,直到抛给公司的大老板,让大老板去处理

注意用法

raise 如果直接写的话,那么就是把错误直接原封不动的抛给上级
如果raise 后追加别的错误类型的话,其实就完成了把错误转化成另外一个类型额操作了,如

    try:
        10/s
    except ZeroDivisionError as e:    
         print('ZeroDivisionError')
         raise ValueError('ValueError')

当然了,这种转化只要符合逻辑就可以,但是切忌瞎转化。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容