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批量按比例缩小图片脚本分享
May 21 Python
python使用reportlab实现图片转换成pdf的方法
May 22 Python
python 剪切移动文件的实现代码
Aug 02 Python
Python实现多线程的两种方式分析
Aug 29 Python
Python3+OpenCV2实现图像的几何变换(平移、镜像、缩放、旋转、仿射)
May 13 Python
Python接口自动化判断元素原理解析
Feb 24 Python
使用sklearn的cross_val_score进行交叉验证实例
Feb 28 Python
Python + selenium + crontab实现每日定时自动打卡功能
Mar 31 Python
python如何判断IP地址合法性
Apr 05 Python
python中有函数重载吗
May 28 Python
python3.9之你应该知道的新特性详解
Apr 29 Python
python使用shell脚本创建kafka连接器
Apr 29 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判断变量类型常用方法
2012/04/24 PHP
PHP的PSR规范中文版
2013/09/28 PHP
php采用curl模仿登录人人网发布动态的方法
2014/11/07 PHP
PHP读取Excel类文件
2017/05/15 PHP
解决php写入数据库乱码的问题
2019/09/17 PHP
JS的数组的扩展实例代码
2008/07/09 Javascript
Extjs grid添加一个图片状态或者按钮的方法
2014/04/03 Javascript
一个简单的jQuery计算器实现了连续计算功能
2014/07/21 Javascript
$(&quot;&quot;).click与onclick的区别示例介绍
2014/09/25 Javascript
如何用jQuery实现ASP.NET GridView折叠伸展效果
2015/09/26 Javascript
详解用webpack2.0构建vue2.0超详细精简版
2017/04/05 Javascript
vue-router路由懒加载和权限控制详解
2017/12/13 Javascript
Vue数据双向绑定原理及简单实现方法
2018/05/18 Javascript
在Vue项目中使用jsencrypt.js对数据进行加密传输的方法
2019/04/17 Javascript
详解iframe跨域的几种常用方法(小结)
2019/04/29 Javascript
微信小程序仿通讯录功能
2020/04/09 Javascript
Vue在H5 项目中使用融云进行实时个人单聊通讯
2020/12/14 Vue.js
[02:37]2018DOTA2亚洲邀请赛赛前采访-EG篇
2018/04/03 DOTA
Python群发邮件实例代码
2014/01/03 Python
Django 前后台的数据传递的方法
2017/08/08 Python
python 查找文件名包含指定字符串的方法
2018/06/05 Python
使用Python实现一个栈判断括号是否平衡
2018/08/23 Python
CSS3实现瀑布流布局与无限加载图片相册的实例代码
2016/12/22 HTML / CSS
Html5上传图片 移动端、PC端通用代码
2016/06/08 HTML / CSS
意大利包包和行李箱销售网站:Bagaglio.it
2021/03/02 全球购物
当x.equals(y)等于true时,x.hashCode()与y.hashCode()可以不相等,这句话对不对
2015/05/02 面试题
银行营业厅大堂经理岗位职责
2014/01/06 职场文书
元旦晚会感言
2014/03/12 职场文书
2014年五四青年节演讲稿范文
2014/04/22 职场文书
民族团结好少年事迹材料
2014/08/19 职场文书
门面房租房协议书
2014/12/01 职场文书
自主招生自荐信格式
2015/03/04 职场文书
酒桌上的开场白
2015/06/01 职场文书
庆祝教师节主题班会
2015/08/17 职场文书
教师信息技术学习心得体会
2016/01/21 职场文书
2016个人先进事迹材料范文
2016/03/01 职场文书