Python 异常处理

Python和很多其他语言一样,支持异常处理。我们可以使用try-catch类似的形式捕获异常,处理异常,或者抛出异常。Python的异常命名惯例和Java语言有些不同, Java的异常一般以Exception结尾,而Python的异常一般以Error结尾。

常见异常

首先我们来看看常见异常,这些异常可能由于编码错误或者其他原因导致。我们打开Python解释器,然后瞎打一通代码,应该就能看到不少异常了。

SyntaxError

系统错误最常见的原因就是编码的缩进错误、或者缺少了分号、冒号等分隔符。例如下面的例子。

if 0>1 
print()
  File "<input>", line 1
    if 0>1
          ^
SyntaxError: invalid syntax

NameError

这个异常通常是由于使用了未定义的名称而引起的。

fuck
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'fuck' is not defined

ZeroDivisionError

这个异常是整数除零错误,一般在数学计算的时候才会出现。

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

ValueError

ValueError异常一般在类型转换失败的时候出现。

int('3fuck')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '3fuck'

处理异常

捕获异常

Java等语言的使用try-catch结构捕获异常,在Python中也是类似的,不过捕获异常使用except关键字。在下面的例子中如果把第一行的fuck注释掉,就可以看到抛出了NameError异常并由except子句捕获了。

fuck = 'fuck!!!'
try:
    fuck
except NameError:
    print('This is a NameError')

多个相似的异常可以使用同一个子句捕获,这需要在except子句中用括号包含多个异常类型。

try:
    fuck
except (NameError, ValueError):
    print('This is a NameError')

如果需要对不同的异常使用不同的异常子句捕获,则可以列出多个异常子句。当抛出的异常是当前异常子句中异常的实例或者子类的实例时,都会匹配到当前子句。需要注意由于所有异常的父类是Excpetion,所以Excpetion类型的异常必须放到最后一个,避免其他异常子句无法执行。

try:
    fuck
except (NameError, ValueError):
    print('This is a NameError')
except SyntaxError:
    print('This is a SystemError')
except Exception:
    print('This is a RuntimeError')

最后一个异常子句的异常类型也可以省略,这样就会捕获所有其他未被捕获的异常。

try:
    fuck
except (NameError, ValueError):
    print('This is a NameError')
except SyntaxError:
    print('This is a SystemError')
except:
    print('This is a RuntimeError')

如果需要获取异常信息,可以使用as关键字声明异常变量,然后就可以在异常子句中使用了。

try:
    fuck
except (NameError, ValueError) as ex:
    print(f'This is a NameError:{ex}')

清理资源

如果异常处理语句中包含了系统资源(文件、网络连接、数据库连接等),我们有义务在使用完毕后及时释放这些资源。Python也提供了相应的机制。

释放资源主要通过两个子句来实现。第一个是else子句,该子句仅当没有抛出异常的时候才执行。如果有异常,这个字句就不会被执行。第二个子句是finally子句,不管有没有异常该语句都会执行。利用这两个语句,我们就可以优雅的关闭资源了。

try:
    raise MyError()
except (NameError, ValueError) as ex:
    print(f'This is a NameError:{ex}')
except MyError:
    print('This is MyError')
else:
    print('Else clause')
finally:
    print('This is finally clause')

抛出异常

我们可以在合适的时候抛出异常,让上级调用者决定如何处理异常。

下面的例子抛出了一个自定义异常。自定义异常是继承了Exception的类。定义之后使用raise语句抛出异常。

class MyError(Exception):
    pass

try:
    raise MyError()
except (NameError, ValueError) as ex:
    print(f'This is a NameError:{ex}')
except MyError:
    print('This is MyError')

如果在except子句中无法处理异常,需要再次向上级抛出,直接使用raise关键字即可。

try:
    raise MyError()
except (NameError, ValueError) as ex:
    print(f'This is a NameError:{ex}')
except MyError:
    print('This is MyError')
    raise 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值