购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.13 异常处理

为增强程序的健壮性,计算机程序的编写也需要考虑如何处理某些异常情况,Python语言提供异常处理功能,本节接下来介绍Python异常处理机制。

2.13.1 捕获异常

捕获异常是通过try-except语句实现的,最基本的try-except语句语法如下。

·try代码块。

try代码块中包含执行过程中可能会抛出异常的语句。

·except代码块。

每个try代码块可以伴随一个或多个except代码块,用于处理try代码块中所有可能抛出的多种异常。except语句中如果省略异常类型,即不指定具体异常,则会捕获所有类型的异常;如果指定具体类型异常,则会捕获该类型异常,以及它的子类型异常。示例代码如下。

示例代码运行后,在控制台输出结果如下。

代码解释如下。

·代码第①行导入了datetime模块,datetime是Python内置的日期时间模块,另外as dt是为导入的模块起一个别名,这可以防止命名冲突。

·代码第②行定义了一个函数,在函数中将传入的字符串转换为日期,并进行格式化。

·代码第③行的strptime函数试图将字符串按照%Y-%m-%d格式转换为日期对象,但并非所有的字符串都是有效的日期字符串,因此调用strptime函数有可能引发ValueError异常。

·代码第④行是捕获ValueError异常,通过ValueError as e表达式获得异常对象。注意本例中的2023-8-18字符串是有效的日期字符串,因此不会抛出异常。如果将字符串改为无效的日期字符串,如2023-B-18,则会打印以下信息。

·代码第⑤行判断当前模块是否为主模块,主模块是程序的入口。

提示

代码第⑤行为什么要判断主模块?这是因为当有多个模块时,其中会有一个模块是主模块,它是程序运行的入口,这类似于C和Java语言中的main()主函数。如果只有一个模块时,可以不用判断是否为主模块,可以不用主函数,在此之前的示例都是没有主函数的。

2.13.2 释放资源

有时try-except语句会占用一些资源,如打开文件、网络连接、数据库连接和使用数据结果集等,这些资源不能通过Python的垃圾收集器回收,需要程序员释放。为了确保这些资源能够被释放,可以使用finally代码块或with as自动资源管理。

1.finally代码块

try-except语句后面还可以跟了一个finally代码块,try-except-finally语句语法如下。

无论try正常结束还是except异常结束,都会执行finally代码块,如图2-17所示。

图2-17 finally代码块流程

使用finally代码块的示例代码如下。

图2-18 test1.txt文件内容

代码解释如下。

·代码第①行定义read_date_from_file函数从test1.txt文件中读取字符串并转换为日期。test1.txt内容如图2-18所示,其中包含一行日期字符串。

·代码第②行通过open函数打开文件。打开文件过程有可能引发FileNotFoundError异常,代码第⑥行是捕获该异常。

·代码第③行读取文件内容,读取过程有可能引发OSError异常,代码第⑦行是捕获该异常。

·代码第④行strip函数删除字符串前后的空格。

·代码第⑧行是finally代码块,在这里通过关闭文件释放资源,见代码第②行file.close()的关闭文件。

2.with as代码块自动资源管理

使用finally代码块释放资源虽然“健壮”,但程序流程比较复杂,这样的程序代码难以维护。为此Python提供了一个with as代码块帮助自动释放资源,它可以替代finally代码块,优化代码结构,提高程序可读性。with as提供了一个代码块,在as后面声明一个资源变量,当with as代码块结束之后自动释放资源。

示例代码如下。

上述代码第①行是使用with as代码块,with语句后面的open(filename)语句可以创建资源对象,然后赋值给as后面的file变量。在with as代码块中包含资源对象相关代码,完成后自动释放资源。采用自动资源管理后,不再需要finally代码块,也不需要自己释放这些资源。 2WpPeQ4OBe5wnyv5quTsEvT3aRdS6LhDVD+npwX2tyqTeuwOmi1STfJ1H1oBb9XL

点击中间区域
呼出菜单
上一章
目录
下一章
×