博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第09章 异常处理
阅读量:2193 次
发布时间:2019-05-02

本文共 3188 字,大约阅读时间需要 10 分钟。

        程序如何处理意料之外的错误呢?异常为这个难题提供了解决方案。例如,如果在读取文件期间,计算机上的其他程序将其删除了,结果将如何呢?如果程序从网站下载网页时,该网站突然崩溃,结果又将如何呢?

        在这些以及众多其他情形下,Python采取 措施是引发异常。异常是一种特殊的错误对象,你可以捕获并检查它们,以决定如何处理错误。

    异常可能改变程序的控制流程。根据发生的时机,异常可能导致执行流程跳出函数或进入处理错误的代码块。

        通常,你无法准确确碇哪一行可能引发异常,这带来了一些棘手的问题。因此,Python提供了一个特殊的异常处理结构,可用于捕获异常,并确保无论是否出现异常都将执行清理代码。

9.1 异常

一个异常的例子是IOError,当你试图打开不存在的文件时将引发这种异常:

        出现异常后,如果不捕获或以任何其他方式进行处理,Python将立即停止运行程序 ,并显示

栈跟踪——异常发生前调用的函数清单。这对确定导致错误的代码行很有帮助。

        在上述栈跟踪中,最后一行表明引发了IOError异常,具体地说,这意味着在当前工作目录中找不到文件unicorn.dat。IOError显示的错误消息随异常的原因而异。

引发异常

正如你从函数open身上看到的,Python内置函数和库函数通常在出现意外情况时引发异常。

例如,除以零将抛出异常:

在Python中,语法错误也会导致异常:

另外,在代码的任何地方都可使用raise语句故意引发异常,如下所示:

Python包含大量内置的异常,这些异常被组织成层次结构,更详细的信息请参阅Python文档。

9.2 捕获异常

异常发生时,你有如下两种选择。

1、忽略异常,让程序崩溃并显示栈跟踪。在开发程序期间,你通常想这样做,因为栈跟踪提供的调试信息很有帮助。

2、捕获异常,并打印友好的错误消息乃至试图修复问题。对于要供非程序员使用的程序,几乎都应这样做。普通用户可不想看到栈跟踪!

        下面的示例演示了如何捕获异常。这里假设你要从用户那里获取一个整数,为此你反复提示用户,直到用户输入有效的整数:

#except.pydef get_age():    while True:        try:            n = int(input('How old are you? '))            return n        except ValueError:            print('Please enter an integer value.')

运行:

        这个函数中的while循环是一个try/except块。你可将可能引发异常的代码放在try中。

        只要try块中的代码出现异常,就将跳过其他所有示执行的语句,立即跳转到except块。在这个示例中,如果出现异常,将跳过return语句。

    如果try块没有引发异常,将忽略(跳过)exceptValueError块。

    在这个示例中,如果用户输入的字符串不是有效的整数,函数int()将引发异常ValueError,进而跳转到except ValueError块并打印错误消息。出现ValueError异常时,将跳过return语句——立即跳转到except块。

     如果用户输入的是有效整数,就不会引发异常,因此Python将接着执行return语句,从而结束函数。

9.2.1 try/except块

        try/except块的工作原理有点像if语句,但存在一个重大不同:if语句根据布尔表达式的结果决定如何做,而try/except块根据是否出现了异常决定如何做。

        同一个函数可能引发多种异常,还可能出于不同原因引发相同的异常。下面是函数int()可能引发的3种异常

这表明int()至少会出于两个不同的原因引发异常ValueError,还至少出于另一个原因引发异常TypeError。

9.2.2 捕获多种异常

你可编写处理多种异常的try/except块。为此,可在except子句中指定多种异常:

 

#try_except.pydef convert_to_int1(s, base):    try:        return int(s, base)    except(ValueError, TypeError):        return 'error'

运行:

如果要分别处理不同的异常,可使用多个except子句:

 

#try_except2.pydef convert_to_int2(s, base):    try:        return int(s, base)    except ValueError:        return 'value error'    except TypeError:        return 'type error'

运行:

9.3.2 捕获所有异常

如果你在except子句中没有指定异常,它将捕获所有异常:

 

#try_except3.pydef convert_to_int3(s, base):    try:        return int(s, base)    except:        return 'except error'

运行:

        这种except子句将捕获所有异常,它不关心发生的是哪种错误,而只关心是否发生了错误。在很多情况下,这就足够了。

9.3 清理操作

在try/except块中, 可包含执行清理操作的finally代码块,如下所示:

 

#except_invert.pydef invert(x):    try:        return 1/x    except ZeroDivisionError:        return 'ZeroDivisionError'    finally:        print('invert(%s) done' % x)

运行:

finally块肯定会执行,它要么在执行try块后执行,要么在执行except块后执行。在不管是否发生异常都要执行某些代码时,这很有用。例如,通常将关闭文件的语句放在finally块中,这样文件肯定会被关闭,即便发生了IOError异常。

with语句

为确保即便发生异常,也将尽早执行清理操作(如关闭文件),还可使用Python语句with。例如 ,请看下面的代码,它在屏幕上打印文件内容,并给每一行都加上行号:

 

#open_file.pydef open_file(fname):    num = 1    f = open(fname)    for line in f:        print('%04d %s' % (num, line), end = '')        num = num + 1

        这里不知道文件对象f将在何时关闭。f通常在for循环结束后关闭,但不知道准确的时间。换句话说,不再需要后,f保持打开 状态多长时间是不确定的,如果其他程序试图访问这个文件,这可能是问题。

        为确保不再需要的文件被尽早关闭,可使用with语句:

 

#with_open_file.pydef with_open_file(fname):    num = 1    f = open(fname)    for line in f:        print('%04d %s' % (num, line), end = '')        num = num +  1

        这个代码片段的屏幕输出与前一个代码片段相同,但使用with语句时,将在for循环结束后立即执行文件对象清理操作(即关闭文件),避免了不再需要的f处于打开状态。

转载地址:http://uyiub.baihongyu.com/

你可能感兴趣的文章
集成测试(一)—— 使用PHP页面请求Spring项目的Java接口数据
查看>>
使用Maven构建的简单的单模块SSM项目
查看>>
Intellij IDEA使用(十四)—— 在IDEA中创建包(package)的问题
查看>>
FastDFS集群架构配置搭建(转载)
查看>>
HTM+CSS实现立方体图片旋转展示效果
查看>>
FFmpeg 命令操作音视频
查看>>
问题:Opencv(3.1.0/3.4)找不到 /opencv2/gpu/gpu.hpp 问题
查看>>
目的:使用CUDA环境变量CUDA_VISIBLE_DEVICES来限定CUDA程序所能使用的GPU设备
查看>>
问题:Mysql中字段类型为text的值, java使用selectByExample查询为null
查看>>
程序员--学习之路--技巧
查看>>
解决问题之 MySQL慢查询日志设置
查看>>
contOS6 部署 lnmp、FTP、composer、ThinkPHP5、docker详细步骤
查看>>
TP5.1模板布局中遇到的坑,配置完不生效解决办法
查看>>
PHPstudy中遇到的坑No input file specified,以及传到linux环境下遇到的坑,模板文件不存在
查看>>
TP5.1事务操作和TP5事务回滚操作多表
查看>>
composer install或composer update 或 composer require phpoffice/phpexcel 失败解决办法
查看>>
TP5.1项目从windows的Apache服务迁移到linux的Nginx服务需要注意几点。
查看>>
win10安装软件 打开时报错 找不到 msvcp120.dll
查看>>
PHPunit+Xdebug代码覆盖率以及遇到的问题汇总
查看>>
PHPUnit安装及使用
查看>>