Python中的异常

1.编程时通常会遇到的两类错误

一类是语法错误,就是不按 Python 规定的语法来写代码,这也是初学者最容易犯的错误,比如:

>>> print(“I love FishC.)
SyntaxError: invalid character '“' (U+201C)

另一类错误并非由于语法错误导致的:

>>> 1 / 0
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    1 / 0
ZeroDivisionError: division by zero

这里虽然 Python 的语法没有错,但由于没有过硬的小学数学知识,同样导致了代码无法正确执行,引发了 ZeroDivisionError 这个异常。

2. 异常机制

Python 通过提供异常机制来识别及响应错误。

Python 的异常机制可以分离出程序中的异常处理代码和正常业务代码,使得程序代码更为优雅,并提高了程序的健壮性。

3. 处理异常

利用 try-except 语句来捕获并处理异常语法如下:

try:
    检测范围
except [expression [as identifier]]:
    异常处理代码

举个例子:

>>> try:
...     1 / 0
... except:
...     print("出错了~")
... 
出错了~

我们可以在 except 后面指定一个异常:

>>> try:
...     1 / 0
... except ZeroDivisionError:
...     print("除数不能为0。")
... 
除数不能为0

后面还有一个可选的 as,这样的话可以将异常的原因给提取出来:

>>> try:
...     1 / 0
... except ZeroDivisionError as e:
...     print(e)
... 
division by zero

其实就是把冒号后面的那部分异常原因给引用出来。

我们还可以将多个可能出现的异常使用元组的形式给包裹起来:

>>> try:
...     1 / 0
...     520 + "FishC"
... except (ZeroDivisionError, ValueError, TypeError):
...     pass
... 

在这个代码中,但凡检测到 try 语句中包含这三个异常中的任意一个,都会执行 pass 语句,直接忽略跳过。

最后也可以单独处理不同的异常,使用多个 except 语句就可以了:

>>> try:
...     1 / 0
...     520 + "FishC"
... except ZeroDivisionError:
...     print("除数不能为0。")
... except ValueError:
...     print("值不正确。")
... except TypeError:
...     print("类型不正确。")
... 
除数不能为0

4.异常处理

try-except-else

try-except 还可以跟 else 进行搭配,它的含义就是当 try 语句没有检测到任何异常的情况下,就执行 else 语句的内容:

>>> try:
...     1 / 0
... except:
...     print("逮到了~")
... else:
...     print("没逮到~")
... 
逮到了~

如果在 try 语句中检测到异常,那么就执行 except 语句的异常处理内容:

>>> try:
...     1 / 1
... except:
...     print("逮到了~")
... else:
...     print("没逮到~")
... 
1.0
没逮到~

try-except-finally

跟 try-except 语句搭配的还有一个 finally,就是说无论异常发生与否,都必须要执行的语句:

>>> try:
...     1 / 0
... except:
...     print("逮到了~")
... else:
...     print("没逮到~")
... finally:
...     print("逮没逮到都会咯吱一声~")
... 
逮到了~
逮没逮到都会咯吱一声~
>>> try:
...     1 / 1
... except:
...     print("逮到了~")
... else:
...     print("没逮到~")
... finally:
...     print("逮没逮到都会咯吱一声~")
... 
1.0
没逮到~
逮没逮到都会咯吱一声~

finally 通常是用于执行那些收尾工作,比如关闭文件的操作:

>>> try:
...     f = open("FishC.txt", "w")
...     f.write("I love FishC.")
... except:
...     print("出错了~")
... finally:
...     f.close()

这样的话,无论 try 语句中是否存在异常,文件都能够正常被关闭。

现在我们的异常处理语法变成了这样:

try:
检测范围
except [expression [as identifier]]:
异常处理代码
[except [expression [as identifier]]:
异常处理代码]*
[else:
没有触发异常时执行的代码]
[finally:
收尾工作执行的代码]

或者:

try:
检测范围
finally:
收尾工作执行的代码

5.异常的嵌套

异常也是可以被嵌套的:

>>> try:
...     try:
...         520 + "FishC"
...     except:
...         print("内部异常!")
...     1 / 0
... except:
...     print("外部异常!")
... finally:
...     print("收尾工作~")
... 
内部异常!
外部异常!
收尾工作~

6.raise语句

使用 raise 语句,我们可以手动的引发异常:

>>> raise ValueError("值不正确。")
Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    raise ValueError("值不正确。")
ValueError: 值不正确。

注意,你不能够 raise 一个并不存在的异常哈:

>>> raise FishCError("小甲鱼说你不行你就不行~")
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    raise FishCError("小甲鱼说你不行你就不行~")
NameError: name 'FishCError' is not defined

由于这个 FishCError 未定义,所以是小甲鱼不行,不是你不行~

还有一种叫异常链,在 raise 后面加个 from:

>>> raise ValueError("这样可不行~") from ZeroDivisionError
ZeroDivisionError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<pyshell#37>", line 1, in <module>
    raise ValueError("这样可不行~") from ZeroDivisionError
ValueError: 这样可不行~

7.assert 语句

assert 语句跟 raise 类似,都是主动引发异常,不过 assert 语句只能引发一个叫 AssertionError 的异常。

这个语句的存在意义,通常是用于代码调试:

>>> s = "FishC"
>>> assert s == "FishC" # 得到期待的结果,通过
>>> assert s != "FishC" # 没有得到期待的结果,引发异常
Traceback (most recent call last):
  File "<pyshell#72>", line 1, in <module>
    assert s != "FishC"
AssertionError

8.利用异常来实现 goto

>>> try:
...     while True:
...         while True:
...             for i in range(10):
...                 if i > 3:
...                     raise
...                 print(i)
...             print("被跳过~")
...         print("被跳过~")
...     print("被跳过~")
... except:
...     print("到这儿来~")
... 
0
1
2
3
到这儿来~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰深入学习计算机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值