Python基础教程之异常详解


Posted in Python onJanuary 10, 2019

一、摘要

Python使用被称为异常 的特殊对象来管理程序执行期间发生的错误。每当发生让Python不知所措的错误时,它都会创建一个异常对象。如果你编写了处理该异常的代码,程序将继续运行;如果你未对异常进行处理,程序将停止,并显示一个traceback,其中包含有关异常的报告。

异常是使用try-except 代码块处理的。try-except 代码块让Python执行指定的操作,同时告诉Python发生异常时怎么办。使用了try-except 代码块时,即便出现异常,程序也将继续运行:显示你编写的友好的错误消息,而不是令用户迷惑的traceback

二、异常实操

处理ZeroDivisionError 异常:try-except&try-except-else

Python基础教程之异常详解

在上述traceback中,指出的错误ZeroDivisionError 是一个异常对象。Python无法按你的要求做时,就会创建这种对象。在这种情况下,Python将停止运行程序,并指出引发了哪种异常,而我们可根据这些信息对程序进行修改。下面我们将使用try-except告诉Python,发生这种错误时怎么办

Python基础教程之异常详解

将导致错误的代码行print(5/0) 放在了一个try 代码块中。如果try 代码块中的代码运行起来没有问题,Python将跳过except 代码块;如果try 代码块中的代码导致了错误,Python将查找这样的except 代码块,并运行其中的代码,即其中指定的错误与引发的错误相同,在这个示例中,try 代码块中的代码引发了ZeroDivisionError 异常,因此Python指出了该如何解决问题的except 代码块,并运行其中的代码。这样,用户看到的是一条友好的错误消息,而不是traceback,如果try-except 代码块后面还有其他代码,程序将接着运行,因为已经告诉了Python如何处理这种错误

使用异常避免崩溃:

发生错误时,如果程序还有工作没有完成,妥善地处理错误就尤其重要。这种情况经常会出现在要求用户提供输入的程序中;如果程序能够妥善地处理无效输入,就能再提示用户提供有效输入,而不至于崩溃。

print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.")
while True:
 first_number = input("\nFirst number: ")
 if first_number == 'q':
  break
 second_number = input("Second number: ")
 if second_number == 'q':
  break
 answer = int(first_number) / int(second_number)
 print(answer)

这个程序没有采取任何处理错误的措施,因此让它执行除数为0的除法运算时,它将崩溃:

Give me two numbers, and I'll divide them.
Enter 'q' to quit.
First number: 5
Second number: 0
Traceback (most recent call last):
 File "division.py", line 9, in <module>
  answer = int(first_number) / int(second_number)
ZeroDivisionError: division by zero

程序崩溃可不好,但让用户看到traceback也不是好主意。不懂技术的用户会被它们搞糊涂,而且如果用户怀有恶意,他会通过traceback获悉你不希望他知道的信息。例如,他将知道你的程序文件的名称,还将看到部分不能正确运行的代码。有时候,训练有素的攻击者可根据这些信息判断出可对你的代码发起什么样的攻击。

通过将可能引发错误的代码放在try-except 代码块中,可提高这个程序抵御错误的能力。错误是执行除法运算的代码行导致的,因此我们需要将它放到try-except 代码块中。这个示例还包含一个else 代码块;依赖于try 代码块成功执行的代码都应放到else 代码块中:

print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.")
while True:
 first_number = input("\nFirst number: ")
 if first_number == 'q':
  break
 second_number = input("Second number: ")
 try:
  answer = int(first_number) / int(second_number)
 except ZeroDivisionError:
  print("You can't divide by 0!")
 else:
  print(answer)

让Python尝试执行try 代码块中的除法运算,这个代码块只包含可能导致错误的代码。依赖于try 代码块成功执行的代码都放在else 代码块中;在这个示例中,如果除法运算成功,我们就使用else 代码块来打印结果。except 代码块告诉Python,出现ZeroDivisionError 异常时该怎么办。如果try 代码块因除零错误而失败,我们就打印一条友好的消息,告诉用户如何避免这种错误。程序将继续运行,用户根本看不到traceback:

Give me two numbers, and I'll divide them.
Enter 'q' to quit.
First number: 5
Second number: 0
You can't divide by 0!
First number: 5
Second number: 2
2.5
First number: q

try-except-else 代码块的工作原理大致如下:Python尝试执行try 代码块中的代码;只有可能引发异常的代码才需要放在try 语句中。有时候,有一些仅在try 代码块成功执行时才需要运行的代码;这些代码应放在else 代码块中。except 代码块告诉Python,如果它尝试运行try 代码块中的代码时引发了指定的异常,该怎么办。通过预测可能发生错误的代码,可编写健壮的程序,它们即便面临无效数据或缺少资源,也能继续运行,从而能够抵御无意的用户错误和恶意的攻击。

处理FileNotFoundError 异常:

使用文件时,一种常见的问题是找不到文件:你要查找的文件可能在其他地方、文件名可能不正确或者这个文件根本就不存在。对于所有这些情形,都可使用try-except 代码块以直观的方式进行处理

filename = 'alice.txt'
with open(filename) as f_obj:
 contents = f_obj.read()

当我们尝试打开的文件(alice.txt)不存在时,python会报如下异常:

Traceback (most recent call last):
 File "alice.py", line 3, in <module>
  with open(filename) as f_obj:
FileNotFoundError: [Errno 2] No such file or directory: 'alice.txt'

在上述traceback中,最后一行报告了FileNotFoundError 异常,这是Python找不到要打开的文件时创建的异常。在这个示例中,这个错误是函数open() 导致的,因此要处理这个错误,必须将try 语句放在包含open() 的代码行之前:

filename = 'alice.txt'
try:
 with open(filename) as f_obj:
  contents = f_obj.read()
 except FileNotFoundError:
  msg = "Sorry, the file " + filename + " does not exist."
  print(msg)

分析文本:

split()函数,看看下边的例子,这个函数干了什么

>>> title = "Alice in Wonderland"
>>> title.split()
['Alice', 'in', 'Wonderland']

split() 以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。结果是一个包含字符串中所有单词的列表,虽然有些单词可能包含标点。为计算Alice in Wonderland 包含多少个单词,我们将对整篇小说调用split() ,再计算得到的列表包含多少个元素,从而确定整篇童话大致包含多少个单词

filename = 'alice.txt'
try:
 with open(filename) as f_obj:
  contents = f_obj.read()
 except FileNotFoundError:
  msg = "Sorry, the file " + filename + " does not exist."
  print(msg)
 else:
  # 计算文件大致包含多少个单词
  words = contents.split()
  num_words = len(words)
  print("The file " + filename + " has about " + str(num_words) + " words.")

将文件alice.txt移到了正确的目录中,让try 代码块能够成功地执行。对变量contents (它现在是一个长长的字符串,包含童话 Alice in Wonderland 的全部文本)调用方法split() ,以生成一个列表,其中包含这部童话中的所有单词。当我们使用len() 来确定这个列表的长度时,就知道了原始字符串大致包含多少个单词,我们打印一条消息,指出文件包含多少个单词,这些代码都放在else 代码块中,因为仅当try 代码块成功执行时才执行它们。输出指出了文件alice.txt包含多少个单词

使用多个文件:

def count_words(filename):
 """计算一个文件大致包含多少个单词"""
 try:
  with open(filename) as f_obj:
   contents = f_obj.read()
 except FileNotFoundError:
  msg = "Sorry, the file " + filename + " does not exist."
  print(msg)
 else:
  # 计算文件大致包含多少个单词
  words = contents.split()
  num_words = len(words)
  print("The file " + filename + " has about " + str(num_words) +
" words.")

filename = 'alice.txt'
count_words(filename)

然后编写一个循环,调用这个函数让他分析多个文件:

filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
 count_words(filename)

在filenames列表中的siddhartha.txt文件是不存在的,我们的程序也能正常运行,使用try-except 代码块提供了两个重要的优点:避免让用户看到traceback;让程序能够继续分析能够找到的其他文件。如果不捕获因找不到siddhartha.txt而引发的FileNotFoundError 异常,用户将看到完整的traceback,而程序将在尝试分析 Siddhartha 后停止运行——根本不分析 Moby Dick 和 Little Women

在前一个示例中,我们告诉用户有一个文件找不到。但并非每次捕获到异常时都需要告诉用户,有时候你希望程序在发生异常时一声不吭,就像什么都没有发生一样继续运行。要让程序在失败时一声不吭,可像通常那样编写try 代码块,但在except 代码块中明确地告诉Python什么都不要做。Python有一个pass 语句,可在代码块中使用它来让Python什么都不要做

def count_words(filename):
"""计算一个文件大致包含多少个单词"""
 try:
  --snip--
 except FileNotFoundError:
  pass
 else:
  --snip--
filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
 count_words(filename)

相比于前一个程序,这个程序唯一不同的地方是pass 语句。现在,出现FileNotFoundError 异常时,将执行except 代码块中的代码,但什么都不会发生。这种错误发生时,不会出现traceback,也没有任何输出。用户将看到存在的每个文件包含多少个单词,但没有任何迹象表明有一个文件未找到

pass 语句还充当了占位符,它提醒你在程序的某个地方什么都没有做,并且以后也许要在这里做些什么。例如,在这个程序中,我们可能决定将找不到的文件的名称写入到文件missing_files.txt中。用户看不到这个文件,但我们可以读取这个文件,进而处理所有文件找不到的问题

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python使用win32com在百度空间插入html元素示例
Feb 20 Python
Python端口扫描简单程序
Nov 10 Python
Python中sort和sorted函数代码解析
Jan 25 Python
取numpy数组的某几行某几列方法
Apr 03 Python
浅谈Django中的数据库模型类-models.py(一对一的关系)
May 30 Python
Python全排列操作实例分析
Jul 24 Python
Python3匿名函数lambda介绍与使用示例
May 18 Python
Django框架视图层URL映射与反向解析实例分析
Jul 29 Python
python实现两个文件夹的同步
Aug 29 Python
python获取时间戳的实现示例(10位和13位)
Sep 23 Python
在pycharm中无法import所安装的库解决方案
May 31 Python
Python实现简繁体转换
Jun 07 Python
Python+OpenCV感兴趣区域ROI提取方法
Jan 10 #Python
python+opencv 读取文件夹下的所有图像并批量保存ROI的方法
Jan 10 #Python
pandas ix &amp;iloc &amp;loc的区别
Jan 10 #Python
python 移动图片到另外一个文件夹的实例
Jan 10 #Python
python将处理好的图像保存到指定目录下的方法
Jan 10 #Python
对python PLT中的image和skimage处理图片方法详解
Jan 10 #Python
python pandas库的安装和创建
Jan 10 #Python
You might like
解决php接收shell返回的结果中文乱码问题
2014/01/23 PHP
php使用多个进程同时控制文件读写示例
2014/02/28 PHP
推荐一本PHP程序猿都应该拜读的书
2014/12/31 PHP
PHP中把对象转换为关联数组代码分享
2015/04/09 PHP
javascript使用location.search的示例
2013/11/05 Javascript
jquery通过select列表选择框对表格数据进行过滤示例
2014/05/07 Javascript
JavaScript实现的使用键盘控制人物走动实例
2014/08/27 Javascript
使用jQuery实现验证上传图片的格式与大小
2014/12/03 Javascript
javascript转换日期字符串为Date日期对象的方法
2015/02/13 Javascript
js完整倒计时代码分享
2016/09/18 Javascript
JQuery Dialog对话框 不能通过Esc关闭的原因分析及解决办法
2017/01/18 Javascript
jquery网页加载进度条的实现
2017/06/01 jQuery
vue2.0实现分页组件的实例代码
2017/06/22 Javascript
React Native之ListView实现九宫格效果的示例
2017/08/02 Javascript
vuejs使用$emit和$on进行组件之间的传值的示例
2017/10/04 Javascript
bootstrap时间控件daterangepicker使用方法及各种小bug修复
2017/10/25 Javascript
基于百度地图api清除指定覆盖物(Overlay)的方法
2018/01/26 Javascript
JavaScript生成指定范围的时间列表
2018/03/19 Javascript
如何自动化部署项目?折腾服务器之旅~
2019/04/16 Javascript
vue中实现回车键登录功能
2020/02/19 Javascript
python 中random模块的常用方法总结
2017/07/08 Python
详解Python使用tensorflow入门指南
2018/02/09 Python
python3正则提取字符串里的中文实例
2019/01/31 Python
python tkinter canvas 显示图片的示例
2019/06/13 Python
Python 利用邮件系统完成远程控制电脑的实现(关机、重启等)
2019/11/19 Python
python 列表、字典和集合的添加和删除操作
2019/12/16 Python
解决python图像处理图像赋值后变为白色的问题
2020/06/04 Python
Pycharm Git 设置方法
2020/09/15 Python
python通过函数名调用函数的几种场景
2020/09/23 Python
python opencv实现图像配准与比较
2021/02/09 Python
使用Python快速打开一个百万行级别的超大Excel文件的方法
2021/03/02 Python
初中三好学生事迹材料
2014/01/13 职场文书
计划生育标语
2014/06/23 职场文书
小学生国庆节演讲稿
2014/09/05 职场文书
扶贫办主任查摆“四风”问题个人对照检查材料思想汇报
2014/10/02 职场文书
2016年大学生党员承诺书
2016/03/24 职场文书