零基础学Python--------第9章 异常处理及程序调试
第9章 异常处理及程序调试
9.1 异常概述
在程序运行过程中,经常会遇到各种各样的错误,这些错误统称为“异常”。这些异常有的是由于开发者将关键字敲错导致的,这类错误多数产生的是SyntaxError:invalid syntax(无效的语法),这将直接导致程序不能运行。这类异常是显式的,在开发阶段很容易被发现。还有一类是隐式的,通常和使用者的操作有关。
实例01:模拟幼儿园分苹果
def division():
'''功能:分苹果'''
print("\n=====================分苹果======================\n")
apple = int(input("请输入苹果的个数:")) # 输入苹果的数量
children = int(input("请输入来了几个小朋友:"))
result = apple//children # 计算每人分几个苹果
remain = apple-result*children # 计算余下几个苹果
if remain>0:
print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result,"个,剩下",remain,"个。")
else:
print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result,"个。")
if __name__ == '__main__':
division() # 调用分苹果的函数
运行程序,当输入苹果和小朋友的数量都是10时:
请输入苹果的个数:10
请输入来了几个小朋友:10
10 个苹果,平均分给 10 个小朋友,每人分 1 个。
如果在输入数量时,不小心把小朋友的人数输成了0:

产生了ZeroDivisionError(除数为0错误)的根源在于算术表达式“10/0”中,0作为除数出现,所以正在执行的程序中被中断(第6行以后,包括第6行的代码都不会被执行)。
Python中还有很多异常。
| 异常 | 描述 |
| NameError | 尝试访问一个没有声明的变量引发的错误 |
| IndexError | 索引超出序列范围引发的错误 |
| IndentationError | 缩进错误 |
| ValueError | 传入错误 |
| KeyError | 请求一个不存在的字典关键字引发的错误 |
| IOError | 输入输出错误(如要读取的文件不存在) |
| ImportError | 当import语句无法找到模块或from 无法在模块中找到相应的名称时引发的错误 |
| AttributeError | 尝试访问未知的对象属性引发的错误 |
| TypeError | 类型不合适引发的错误 |
| MemoryError | 内存不足 |
| ZeroDivisionError | 除数为0 引发的错误 |
9.2 异常处理语句
在程序开发时,有些错误并不是每次运行都会出现。
下面将详细介绍Python中提供的异常处理语句。
9.2.1 try...eccept
在Python中,提供了try...except语句捕获并处理异常。在使用时,把可能产生异常的代码放在try 语句块中,把处理结果放在except 语句块中,这样,当try 语句块中的代码出现错误时,就会执行except语句块中的代码,如果try 语句块中的代码没有错误,那么except 语句块将不会执行。具体的语法格式如下:
try:
block1
except [ExceptionName [as alias]]:
block2
参数说明:
- block1:表示可能出现错误的代码块。
- ExceptionName [as alias]:可选参数,用于指定要捕获的异常。其中,ExceptionName表示要捕获的异常名称,如果在其右侧加上as alias,则表示为当前的异常指定一个别名,通过该别名,可以记录异常的具体内容。
说明:在使用try...except语句捕获异常时,如果在except后面不指定异常名称,则表示捕获全部异常。
- block2:表示进行异常处理的代码块。在这里可以输出固定的提示信息,也可以通过别名输出异常的具体内容。
说明:使用try...except语句捕获异常后,当程序出错时,输出错误信息后,程序会继续执行。
实例02:模拟幼儿园分苹果(除数不能为0)
对“if __name__ =='__main__':”语句下面的代码进行修改,应用try...except语句捕获执行division()函数可能抛出的ZeroDivisionError(除数为零)异常,修改后的代码如下:
def division():
'''功能:分苹果'''
print("\n=====================分苹果======================\n")
apple = int(input("请输入苹果的个数:")) # 输入苹果的数量
children = int(input("请输入来了几个小朋友:"))
result = apple//children # 计算每人分几个苹果
remain = apple-result*children # 计算余下几个苹果
if remain>0:
print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result,"个,剩下",remain,"个。")
else:
print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result,"个。")
if __name__ == '__main__':
try: # 捕获异常
division() # 调用分苹果的函数
except ZeroDivisionError: # 处理异常
print("\n出错了 ~_~ ——苹果不能被0个小朋友分!")
执行以上的代码,输入苹果的数量为10,小朋友的人数为0时,将不再抛出异常:

目前,我们只处理了除数为0的情况,如果将苹果和小朋友的数量输入成小数或者不是数字会是什么结果呢?

可以看出,程序中要求输入整数,而实际输入的是小数,则抛出ValueError(传入的值错误)异常。要解决该问题,可以在实例02的代码中,为try...except语句再添加一个except语句,用于处理抛出ValueError异常的情况。修改后的代码如下:
def division():
'''功能:分苹果'''
print("\n=====================分苹果======================\n")
apple = int(input("请输入苹果的个数:")) # 输入苹果的数量
children = int(input("请输入来了几个小朋友:"))
result = apple//children # 计算每人分几个苹果
remain = apple-result*children # 计算余下几个苹果
if remain>0:
print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result,"个,剩下",remain,"个。")
else:
print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result,"个。")
if __name__ == '__main__':
try: # 捕获异常
division() # 调用分苹果的函数
except ZeroDivisionError: # 处理异常
print("\n出错了 ~_~ ——苹果不能被0个小朋友分!")
except ValueError as e: # 处理ValueError异常
print("输入错误:",e) # 输出错误原因
再次运行程序:

多学两招:
在捕获异常时,如果需要同时处理多个异常也可以采用下面的代码实现:
try: # 捕获异常
division() # 调用分苹果的函数
except (ZeroDivisionError,ValueError) as e: # 处理异常
print("输入错误:",e) # 输出错误原因
即在except语句后面使用一对小括号将可能出现的异常名称括起来,多个异常名称之间使用逗号分隔。如果想要显示具体的出错原因,那么再加上as指定一个别名。
9.2.2 try...except...else 语句
在Python中国,还有另一种异常处理结构,它是try...except...else语句,也就是在原来try...except语句的基础上再添加一个else子句,用于指定当try语句块中没有发现异常时要执行的语句块。该语句块中的内容当try语句中发现异常,将不被执行。例如,实例02进行修改,实现当division()函数被执行后没有抛出异常时,输出文字“分苹果顺利完成...”。修改后的代码如下:
def division():
'''功能:分苹果'''
print("\n=====================分苹果======================\n")
apple = int(input("请输入苹果的个数:")) # 输入苹果的数量
children = int(input("请输入来了几个小朋友:"))
result = apple//children # 计算每人分几个苹果
remain = apple-result*children # 计算余下几个苹果
if remain>0:
print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result,"个,剩下",remain,"个。")
else:
print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result,"个。")
if __name__ == '__main__':
try: # 捕获异常
division() # 调用分苹果的函数
except ZeroDivisionError : # 处理异常
print("\n出错了 ~_~ ——苹果不能被0个小朋友分!")
except ValueError as e: # 处理ValueError异常
print("输入错误:",e) # 输出错误原因
else: # 没有抛出异常时执行
print("分苹果顺利完成...")
执行以上代码:

9.2.3 try...except...finally 语句
完整的异常处理语句应该包含finally 代码块,通常情况下,无论程序中有无异常产生,finally 代码块中的代码都会被执行,其语法格式如下:
try:
block1
except [ExceptionName [as alias]]:
block2
fianlly:
block3
对于try...except...finally 语句的理解并不复杂,它只是比try...except 语句多了一个finally 语句,如果程序中有一些在任何情形中都必须执行的代码,那么就可以将它们放在finally 代码块中。
说明:使用except 子句是为了允许处理异常。无论是否引起了异常,使用finally 子句都是可以执行清理代码。如果分配了有限的资源(如打开文件),则应将释放这些资源的代码放置在finally 代码块中。
例如,在对实例02进行修改,实现当division() 函数在执行时无论是否抛出异常,都输出文字“进行了一次分苹果操作”。修改后的代码如下:
def division():
'''功能:分苹果'''
print("\n=====================分苹果======================\n")
apple = int(input("请输入苹果的个数:")) # 输入苹果的数量
children = int(input("请输入来了几个小朋友:"))
result = apple//children # 计算每人分几个苹果
remain = apple-result*children # 计算余下几个苹果
if remain>0:
print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result,"个,剩下",remain,"个。")
else:
print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result,"个。")
if __name__ == '__main__':
try: # 捕获异常
division() # 调用分苹果的函数
except ZeroDivisionError : # 处理异常
print("\n出错了 ~_~ ——苹果不能被0个小朋友分!")
except ValueError as e: # 处理ValueError异常
print("输入错误:",e) # 输出错误原因
else: # 没有抛出异常时执行
print("分苹果顺利完成...")
finally: # 无论是否抛出异常都执行
print("进行了一次分苹果操作。")
执行程序:

至此,已经介绍了异常处理语句的try....except、try...except...else 和 try...except...finally 等形式。

异常处理语句的不同子句的执行关系
9.2.4 使用raise 语句抛出异常
如果某个函数或方法可能会产生异常,但不想在当前函数或方法中处理这个异常,则可以使用raise 语句在函数或方法中抛出异常。raise 语句的语法格式如下:
raise [ExceptionName[(reason)]]
其中,ExceptionName[(reason)]为可选参数,用于指定抛出的异常名称以及异常信息的相关描述。如果省略,就会把当前的错误原样抛出。
说明:ExceptionName[(reason)]参数中的“(reason)”也可以省略,如果省略,则在抛出异常时,不附带任何描述信息。
例如,修改实例02,加入限制苹果数量必须大于或等于小朋友的数量,从而保证每个小朋友都能至少分到一个苹果。
实例03:模拟幼儿园分苹果(每个人至少分到一个苹果)
在第5行代码“children = int(input("请输入来了几个小朋友:"))”的下方添加一个if 语句,实现当苹果的数量小于小朋友的数量时,应用raise 语句抛出一个ValueError 异常,接下来再在最后一行语句的下方添加except 语句处理ValueError 异常。
def division():
'''功能:分苹果'''
print("\n=====================分苹果======================\n")
apple = int(input("请输入苹果的个数:")) # 输入苹果的数量
children = int(input("请输入来了几个小朋友:"))
if apple < children:
raise ValueError("苹果太少了,不够分...")
result = apple//children # 计算每人分几个苹果
remain = apple - result*children # 计算余下几个苹果
if remain>0:
print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result,"个,剩下",remain,"个。")
else:
print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result,"个。")
if __name__ == '__main__':
try: # 捕获异常
division() # 调用分苹果的函数
except ZeroDivisionError : # 处理ZeroDivisionError异常
print("\n出错了 ~_~ ——苹果不能被0个小朋友分!")
except ValueError as e: # ValueError
print("\n出错了~_~ ——",e)
执行程序:

说明:在应用raise 抛出异常时,要尽量选择合理的异常对象,而不应该抛出一个与实际内容不相关的异常。流入,在实例03中,想要处理的是一个和值有关的异常,这时就不应该抛出一个IndentationError异常。
9.3 程序调试
零基础学Python--------第9章 异常处理及程序调试的更多相关文章
- [零基础学python]为什么要开设本栏目
这个栏目的名称叫做"零基础学Python". 如今网上已经有不少学习python的课程.当中也不乏精品.按理说,不缺少我这个基础类型的课程了.可是,我注意到一个问题.无论是课程还是 ...
- 零基础学python》(第二版)
---恢复内容开始--- 零基础学python>(第二版) python学习手册 可以离线下载, .chn格式, 插入小幽默笑话,在学习累的时候看看笑话 放松一下 欢迎下载转载,请注明出处,谢 ...
- 零基础学python,python视频教程
零基础学python,python视频教程 这是我收集到的互联网上的视频资源,所有内容均来自互联网.仅供学习使用. 目前我在也在学习过程中,会把学习过程中遇到问题以及解决问题的方式,总结到我的公众号[ ...
- 小甲鱼零基础学python第25讲课后习题动手练习--通讯录
小甲鱼零基础学python第25讲课后习题动手练习---通讯录 **************************通讯录要求******************************* 输入指令: ...
- Python学习课程零基础学Python
python学习课程,零基础Python初学者应该怎么去学习Python语言编程?python学习路线这里了解一下吧.想python学习课程?学习路线网免费下载海量python教程,上班族也能在家自学 ...
- 零基础学python之构建web应用(入门级)
构建一个web应用 前面的学习回顾: IDLE是Python内置的IDE,用来试验和执行Python代码,可以是单语句代码段,也可以是文本编辑器中的多语句程序. 四个内置数据结构:列表.字典.集合和元 ...
- 零基础学Python不迷茫——基本学习路线及教程!
什么是Python? 在过去的2018年里,Python成功的证明了它自己有多火,它那“简洁”与明了的语言成功的吸引了大批程序员与大数据应用这的注意,的确,它的实用性的确是配的上它的热度. Pyt ...
- 零基础学Python 3之环境准备
一. 配置python 3 环境 1. Python 3 下载 64位 https://www.python.org/ftp/python/3.4.2/python-3.4.2.amd64.msi 3 ...
- 零基础学python之函数与模块(附详细的代码和安装发布文件过程)
代码重用——函数与模块 摘要:构建函数,创建模块,安装发布文件,安装pytest和PEP 8插件,确认PEP8兼容性以及纠错 重用代码是构建一个可维护系统的关键. 代码组是Python中对块的叫法. ...
随机推荐
- linux根目录下的各文件夹含义说明
在早期的 UNIX 系统中,各个厂家各自定义了自己的 UNIX 系统文件目录,比较混乱. Linux 面世不久后,对文件目录进行了标准化,于1994年对根文件目录做了统一的规范, 推出 FHS ( F ...
- 分享波面经【2年经验】【linux c++】
快三个月没写博客了,一直在忙着准备面试和去面试的路上,所以没时间写,也没什么想写的.现在告一段落,就总结一波! 面经 很感谢一些公司能给我面试机会,有的公司真的会拿学历卡人,也不想多说! 17年毕业, ...
- WebGL three.js学习笔记 创建three.js代码的基本框架
WebGL学习----Three.js学习笔记(1) webgl介绍 WebGL是一种3D绘图协议,它把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的 ...
- Java-每日编程练习题②(数组练习)
1.有一个已经排好序的数组.现输入一个数,要求按原来的规律将它插入数组中. 分析思路: 先通过Random类随机创建一个数组,再调用Arrays类中的排序方法sort排好序,然后再开始实现功能. 按原 ...
- redis增删查改数据Util
目录 (1)需要导入的包 (2)redis配置文件 (3)RedisUtil类 (1)需要导入的包 <dependency> <groupId>org.springframew ...
- Java集合学习总结
java集合 collection public interface Collection<E> extends Iterable<E> List public interfa ...
- 设计模式系列1:单例模式(Singleton Pattern)
定义 保证一个类仅有一个实例,并提供一个该实例的全局访问点. --<设计模式GoF> UML类图 使用场景 当类只能有一个实例并且用户可以从一个众所周知的访问点访问它时. 创建一个对象需 ...
- flex布局基本语法
注 : 本文章按照菜鸟教程 Flex布局语法教程为原型稍加修改,以方便自己学习. 菜鸟教程地址:http://www.runoob.com/w3cnote/flex-grammar.html 2009 ...
- ggsci: error while loading shared libraries: libnnz11.so
[oracle@localhost goldengate]$ ./ggsci ./ggsci: error while loading shared libraries: libnnz11.so: c ...
- vue cli 3.x 项目部署到 github pages
github pages 是 github 免费为用户提供的服务,写博客,或者部署一些纯静态项目. 最近将 vue cli 3.x 初始化项目部署到 github pages,踩了一些坑,记录如下. ...