前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >让程序更健壮的异常处理

让程序更健壮的异常处理

原创
作者头像
mr.songw
修改2021-02-01 18:18:21
5160
修改2021-02-01 18:18:21
举报
文章被收录于专栏:Python 自习室Python 自习室

什么是异常?

异常是在程序运行过程中发生的错误,当异常发生时,需要对异常进行处理,否则整个程序将崩溃。举个例子:

代码语言:txt
复制
In [1]: print(1 / 0)
   ...: print("Done!")
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-1-d46a17880c1e> in <module>
----> 1 print(1 / 0)
      2 print("Done!")

ZeroDivisionError: division by zero

例子中的 1 / 0 触发了 ZeroDivisionError 异常,由于没有对异常进行处理,导致了程序的崩溃,后面的语句没有再继续执行。

异常的处理

异常发生时,如果直接导致了程序的崩溃,不论对用户还是对开发者来说都是不友好的,这便要求我们在异常发生时,对异常进行处理。

try-except

tryexcept 语句块可以用来捕获和处理异常,try 后面跟的是需要捕获异常的代码,except 后面跟的是捕获到异常后需要做的处理。每一个 try 语句块后面必须跟上一个 except 语句块,即使 except 语句块什么也不做。

image:2FC3BC63-310B-4FB6-8AC0-FA73E8B9505F-452-0001167B13C20CB0/try_except.png

举个例子:

代码语言:txt
复制
In [2]: try:
   ...:     print(1 / 0)
   ...: except ZeroDivisionError:
   ...:     print("ZeroDivisionError happened!")
   ...:
   ...:
   ...: print("Done!")
ZeroDivisionError happened!
Done!

加了异常捕获和处理代码之后,当发生异常时,整个程序没有崩溃,而是继续执行后面的代码,所以输出了 Done!

try 语句块后面可以跟上多个 except 语句块。

代码语言:txt
复制
In [8]: try:
   ...:     print(1 / 0)
   ...:     with open('test.log') as file:
   ...:         read_data = file.read()
   ...: except ZeroDivisionError:
   ...:     print("ZeroDivisionError happened!")
   ...: except FileNotFoundError:
   ...:     print("FileNotFoundError happened!")
   ...:
   ...:
   ...: print("Done!")
ZeroDivisionError happened!
Done!

在执行代码 print(1 / 0) 时,发生了除 0 异常,所以没有执行后面的打开文件的代码,后面的异常处理代码输出了 ZeroDivisionError happened!。如果我们颠倒下代码的顺序:

代码语言:txt
复制
In [9]: try:
   ...:     with open('test.log') as file:
   ...:         read_data = file.read()
   ...:     print(1 / 0)
   ...: except ZeroDivisionError:
   ...:     print("ZeroDivisionError happened!")
   ...: except FileNotFoundError:
   ...:     print("FileNotFoundError happened!")
   ...:
   ...:
   ...: print("Done!")
FileNotFoundError happened!
Done!

代码颠倒之后,在执行打开文件的代码时,发生了文件不存在的异常,所以没有执行后面的代码,后面的异常处理代码输出了 FileNotFoundError happened!

try-except-else

try-except 语句块后面可以跟上 else 语句块,当没有异常发生时,会执行 else 语句块中的代码。

image:05830639-9C5D-4021-B3C2-33959725A16E-452-0001167DFC0379A8/try_except_else.png

举个例子:

代码语言:txt
复制
In [3]: try:
   ...:     print(1 / 1)
   ...: except ZeroDivisionError:
   ...:     print("ZeroDivisionError happened!")
   ...: else:
   ...:     print("Exception not happened")
   ...:
   ...:
   ...: print("Done!")
1.0
Exception not happened
Done!

由于没有发生异常,所以 else 语句块中的代码得到了执行,输出了 Exception not happened

try-except-else-finally

try-except-else 语句块后面还可以跟上 finally 语句块,不管有没有发生异常,finally 语句块中的代码都会被执行。

image:0DCAD16A-2492-43A0-A201-DB7D3125DCBF-452-00011680ED93FF4E/try_except_else_finally.png

举个例子:

  • 没有发生异常时
代码语言:txt
复制
In [4]: try:
   ...:     print(1 / 1)
   ...: except ZeroDivisionError:
   ...:     print("ZeroDivisionError happened!")
   ...: else:
   ...:     print("Exception not happened")
   ...: finally:
   ...:     print("Finally is executed!")
   ...:
   ...:
   ...: print("Done!")
1.0
Exception not happened
Finally is executed!
Done!

没有发生异常时,finally 语句块中的代码得到了执行,输出了 Finally is executed!

  • 发生异常时
代码语言:txt
复制
In [5]: try:
   ...:     print(1 / 0)
   ...: except ZeroDivisionError:
   ...:     print("ZeroDivisionError happened!")
   ...: else:
   ...:     print("Exception not happened")
   ...: finally:
   ...:     print("Finally is executed!")
   ...:
   ...:
   ...: print("Done!")
ZeroDivisionError happened!
Finally is executed!
Done!

发生异常时,finally 语句块中的代码同样得到了执行,输出了 Finally is executed! 。因此,不管有没有发生异常,finally 语句块中的代码都会被执行。finally 在释放资源时会特别有用。

抛出异常

前面讲的是异常出现时,可以做的处理。另外,我们也可以主动跑出异常。主动抛出异常使用 raise 关键字。举个例子:

代码语言:txt
复制
In [7]: x = 10
   ...: if x > 5:
   ...:     raise Exception('x should not exceed 5. The value of x was: {}'.format(x))
   ...:
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-7-5c2e6c28125c> in <module>
      1 x = 10
      2 if x > 5:
----> 3     raise Exception('x should not exceed 5. The value of x was: {}'.format(x))
      4

Exception: x should not exceed 5. The value of x was: 10

x > 5 时,主动抛出异常。

总结

  • 位于 try 语句块中的代码都会被执行,直到遇到了异常。
  • except 语句块中的代码用来捕获和处理 try 语句块中的异常。
  • 把没有异常发生时需要执行的代码放在 else 语句块中。
  • 把不管有没有异常发生都需要执行的代码放在 finally 语句块中。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是异常?
  • 异常的处理
    • try-except
      • try-except-else
        • try-except-else-finally
        • 抛出异常
        • 总结
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档