Python学习笔记9——异常处理
处理异常
如果执行到程序中某处抛出了异常,程序就会被终止并退出。你可能会问,那有没有什么办法可以不终止程序,让其照样运行下去呢?答案当然是肯定的,这也就是我们所说的异常处理,通常使用 try 和 except 来解决,比如:
try:
s = input('please enter two numbers separated by comma: ')
num1 = int(s.split(',')[0].strip())
num2 = int(s.split(',')[1].strip())
...
except ValueError as err:
print('Value Error: {}'.format(err)) print('continue')
...
这里默认用户输入以逗号相隔的两个整形数字,将其提取后,做后续的操作(注意 input 函数会将输入转换为字符串类型)。如果我们输入a,b,程序便会抛出异常invalid literal for int() with base 10: 'a',然后跳出 try 这个 block。
由于程序抛出的异常类型是 ValueError,和 except block 所 catch 的异常类型相匹配,所以 except block 便会被执行,最终输出Value Error: invalid literal for int() with base 10: 'a',并打印出continue。
please enter two numbers separated by comma: a,b
Value Error: invalid literal for int() with base 10: 'a'
continue
except block 只接受与它相匹配的异常类型并执行,如果程序抛出的异常并不匹配,那么程序照样会终止并退出。
所以,还是刚刚这个例子,如果我们只输入1,程序抛出的异常就是IndexError: list index out of range,与 ValueError 不匹配,那么 except block 就不会被执行,程序便会终止并退出(continue 不会被打印)。
please enter two numbers separated by comma: 1
IndexError Traceback (most recent call last)
IndexError: list index out of range
不过,很显然,这样强调一种类型的写法有很大的局限性。那么,该怎么解决这个问题呢?
其中一种解决方案,是在 except block 中加入多种异常的类型,比如下面这样的写法:
try:
s = input('please enter two numbers separated by comma: ')
num1 = int(s.split(',')[0].strip())
num2 = int(s.split(',')[1].strip())
...
except (ValueError, IndexError) as err:
print('Error: {}'.format(err)) print('continue')
...
或者第二种写法:
try:
s = input('please enter two numbers separated by comma: ')
num1 = int(s.split(',')[0].strip())
num2 = int(s.split(',')[1].strip())
...
except ValueError as err:
print('Value Error: {}'.format(err))
except IndexError as err:
print('Index Error: {}'.format(err)) print('continue')
...
这样,每次程序执行时,except block 中只要有一个 exception 类型与实际匹配即可。
不过,很多时候,我们很难保证程序覆盖所有的异常类型,所以,更通常的做法,是在最后一个 except block,声明其处理的异常类型是 Exception。Exception 是其他所有非系统异常的基类,能够匹配任意非系统异常。那么这段代码就可以写成下面这样:
try:
s = input('please enter two numbers separated by comma: ')
num1 = int(s.split(',')[0].strip())
num2 = int(s.split(',')[1].strip())
...
except ValueError as err:
print('Value Error: {}'.format(err))
except IndexError as err:
print('Index Error: {}'.format(err))
except Exception as err:
print('Other error: {}'.format(err)) print('continue')
...
或者,你也可以在 except 后面省略异常类型,这表示与任意异常相匹配(包括系统异常等):
try:
s = input('please enter two numbers separated by comma: ')
num1 = int(s.split(',')[0].strip())
num2 = int(s.split(',')[1].strip())
...
except ValueError as err:
print('Value Error: {}'.format(err))
except IndexError as err:
print('Index Error: {}'.format(err))
except:
print('Other error') print('continue')
...
需要注意,当程序中存在多个 except block 时,最多只有一个 except block 会被执行。换句话说,如果多个 except 声明的异常类型都与实际相匹配,那么只有最前面的 except block 会被执行,其他则被忽略。
异常处理中,还有一个很常见的用法是 finally,经常和 try、except 放在一起来用。无论发生什么情况,finally block 中的语句都会被执行,哪怕前面的 try 和 excep block 中使用了 return 语句。
一个常见的应用场景,便是文件的读取:
import sys
try:
f = open('file.txt', 'r')
.... # some data processing
except OSError as err:
print('OS error: {}'.format(err))
except:
print('Unexpected error:', sys.exc_info()[0])
finally:
f.close()
这段代码中,try block 尝试读取 file.txt 这个文件,并对其中的数据进行一系列的处理,到最后,无论是读取成功还是读取失败,程序都会执行 finally 中的语句——关闭这个文件流,确保文件的完整性。因此,在 finally 中,我们通常会放一些无论如何都要执行的语句。
值得一提的是,对于文件的读取,我们也常常使用 with open,你也许在前面的例子中已经看到过,with open 会在最后自动关闭文件,让语句更加简洁。
自定义异常
前面的例子里充斥了很多 Python 内置的异常类型,你可能会问,我可以创建自己的异常类型吗?
答案是肯定是,Python 当然允许我们这么做。下面这个例子,我们创建了自定义的异常类型 MyInputError,定义并实现了初始化函数和 str 函数(直接 print 时调用):
class MyInputError(Exception):
"""Exception raised when there're errors in input"""
def __init__(self, value): # 自定义异常类型的初始化
self.value = value
def __str__(self): # 自定义异常类型的 string 表达形式
return ("{} is invalid input".format(repr(self.value))) try:
raise MyInputError(1) # 抛出 MyInputError 这个异常
except MyInputError as err:
print('error: {}'.format(err))
如果你执行上述代码块并输出,便会得到下面的结果:
error: 1 is invalid input
实际工作中,如果内置的异常类型无法满足我们的需求,或者为了让异常更加详细、可读,想增加一些异常类型的其他功能,我们可以自定义所需异常类型。不过,大多数情况下,Python 内置的异常类型就足够好了。
Python学习笔记9——异常处理的更多相关文章
- Python学习笔记之异常处理
1.概念 Python 使用异常对象来表示异常状态,并在遇到错误时引发异常.异常对象未被捕获时,程序将终止并显示一条错误信息 >>> 1/0 # Traceback (most re ...
- 【Python学习笔记】异常处理try-except
Python异常处理 我们一般使用try-except语句来进行异常处理. 使用except Exception as err可以统一捕捉所有异常,而也可以分开处理单个异常. # 分开捕捉单个异常 t ...
- python学习笔记(异常处理)
上次提到正则表达式 当未匹配到数据返回值 None 再使用 match.group 会出现异常 AttributeError 为了避免异常我改成“ match != None” 这次加入异常处理 #! ...
- python学习笔记(八):异常处理
一.异常处理 在程序运行过程中,总会遇到各种各样的错误.程序一出错就停止运行了,那我们不能让程序停止运行吧,这时候就需要捕捉异常了,通过捕捉到的异常,我们再去做对应的处理. 下面我们先写一个函数,实现 ...
- Python 学习笔记18 异常处理
我们在编码的过程中,难免会遇到一些错误和异常, 这时候程序会异常退出,并且会抛出错误信息: 比如: print(1/0) ''' 输出: Traceback (most recent call las ...
- python学习笔记(六)文件夹遍历,异常处理
python学习笔记(六) 文件夹遍历 1.递归遍历 import os allfile = [] def dirList(path): filelist = os.listdir(path) for ...
- Python学习笔记进阶篇——总览
Python学习笔记——进阶篇[第八周]———进程.线程.协程篇(Socket编程进阶&多线程.多进程) Python学习笔记——进阶篇[第八周]———进程.线程.协程篇(异常处理) Pyth ...
- python学习笔记目录
人生苦短,我学python学习笔记目录: week1 python入门week2 python基础week3 python进阶week4 python模块week5 python高阶week6 数据结 ...
- Python学习笔记之基础篇(-)python介绍与安装
Python学习笔记之基础篇(-)初识python Python的理念:崇尚优美.清晰.简单,是一个优秀并广泛使用的语言. python的历史: 1989年,为了打发圣诞节假期,作者Guido开始写P ...
随机推荐
- idea中创建maven的Javaweb工程并进行配置
学完maven后,可以创建maven的javaweb工程,在创建完成后还需要一些配置,下面来说下具体步骤,在这里我创建的是一个模块,创建web项目的方式和创建模块一样 1.创建一个模块,点new-Mo ...
- 数据结构(集合)学习之Map(二)
集合 框架关系图 补充:HashTable父类是Dictionary,不是AbstractMap. 一:HashMap中的链循环: 一般来说HashMap中的链循环会发生在多线程操作时(虽然HashM ...
- 【剑指Offer】61、把二叉树打印成多行
题目描述 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行. 题解一:BFS public static ArrayList<ArrayList<Integer>> ...
- [译]C# 7系列,Part 10: Span<T> and universal memory management Span<T>和统一内存管理
原文:https://blogs.msdn.microsoft.com/mazhou/2018/03/25/c-7-series-part-10-spant-and-universal-memory- ...
- JAVA->查询并显示输入根目录下全部的文件所在目录路径
public static boolean qf(File f,boolean a){ boolean b=false; if(a==true){ File[] fl=f.li ...
- Spring IoC Container源码分析(二)-bean初始化流程
准备 Person实例 @Data public class Person { private String name; private int age; } xml bean配置 <?xml ...
- C#中怎样将数组的顺序打乱随机排序
场景 在ZedGraph随机生成颜色时需要从颜色数组中取颜色对象. Color数组存取的是System.Drawing.Color的颜色. 其顺序是相邻的颜色,颜色差距不大,在取颜色时按顺序取颜色时, ...
- js对象赋值
看到一道题: 根据包名,在指定空间中创建对象 效果 namespace({a: {test: 1, b: 2}}, 'a.b.c.d') 结果 {a: {test: 1, b: {c: {d: {}} ...
- 使用word时在方块中打钩
☑ 方法一: 第一步: 输入:2611 第二步: 选中2611 第三步: 按Alt + X Get : ☑ 同样:用2610代替2611会得到☐ ☐2610 ☑2611 方法二 1.选择[插入]-- ...
- 牛客练习赛53 C题bitset
题目链接https://ac.nowcoder.com/acm/contest/1114/C #include<bits/stdc++.h> using namespace std; #d ...