Python从入门到实战(一)——Python基础
Python从入门到实战(二)——程序流程控制
Python从入门到实战(三)——组合数据类型
Python从入门到实战(四)——函数
Python从入门到实战(五)——模块和包
Python从入门到实战(六)——文件
Python从入门到实战(七)——面向对象
Python从入门到实战(八)——异常
Python从入门到实战(九)——多线程
Python从入门到实战(十)——爬虫
文章目录
什么是异常
打开一个不存在的文件123.txt,当找不到123.txt文件时,就会抛出给我们一个IOError类型的错误,No such file or directory:123.txt(没有123.txt这样的文件或目录)
如何捕获异常
捕获异常
try...except...
语句:
try
子句中的代码块放置可能出现异常的语句,except
子句中的代码块处理异常:
try:
try块 # 被监控的语句
except Exception as e
except块 # 处理异常的语句
下面的代码显示了使用try...except...
语句诊断异常的过程。
lst = ['China', 'America', 'England', 'France']
try:
print(lst[4])
except IndexError as e:
print('列表元素的下标越界')
捕获多个异常
带多个except的try语句
输入两数,求两数相除的结果。
在数值输入应检测输入的被除数和除数是否是数值,如果输入的字符则视为无效。
在进行除操作时,应检测除数是否为0。
try:
x = float(input("请输入被除数:"))
y = float(input("请输入除数:"))
z = x/y
except ZeroDivisionError as e1:
print("除数不能为零")
except ValueError as e2:
print("被除数和除数应为数值类型")
还可以用元组的形式
try:
x = float(input("请输入被除数:"))
y = float(input("请输入除数:"))
z = x/y
except (ZeroDivisionError,ValueError) as e:
# 如果想通过一次except捕获到多个异常可以用一个元组的方式
# e里会保存捕获到的异常的信息描述
print(e)
捕获所有异常
用Exception
对应所有异常
try:
open('a.txt')
except Exception as result:
print('捕获到了异常!')
print(result)
else语句
try...except...else
语句:
如果try
范围内捕获了异常,就执行except
块;如果try
范围内没有捕获异常,就执行else
块。
下面的示例引入循环结构,可以实现重复输入字符串序号,直到检测序号不越界而输出相应的字符串
lst = ['China', 'America', 'England', 'France']
print('请输入字符串的序号')
while True:
n = int(input())
try:
print(lst[n])
except IndexError as e:
print('列表元素的下标越界,请重新输入字符串的序号')
else:
break
finally语句
try...finally...
语句:
在程序中,如果一个代码段必须要执行,即无论异常是否产生都要执行,那么此时就需要使用finally
。比如文件关闭,释放锁,把数据库连接还给连接池等。
下面的示例通过try...finally...
语句使得无论文件打开是否正确或时readline()
调用失败,都能够正常关闭文件。
try:
f = open('123.txt')
try:
content = f.readline()
print(content)
print('读文件成功')
except:
print('读文件出现异常')
finally:
f.close()
print('关闭文件')
except IOError:
print('没有这个文件')
异常的特点
try语句嵌套
try:
f = open('1.txt')
try:
content = f.readline()
10//0 # 1.这里会出现被0除的异常
print(content)
print('读文件成功')
except IOError: # 2.这里只捕获了读文件异常,没有捕获被0除的异常
print('读文件出现异常')
finally:
f.close()
print('关闭文件')
except: # 3.这里捕获了被0除的异常
print('出现了一些读文件以外的异常!')
如果try
嵌套,那么如果里面的try
没有捕获到这个异常,那么外面的try
会接收到这个异常,然后进行处理,如果外边的try
依然没有捕获到,那么再进行传递…
异常的传递
def test1():
print("-----test1-1-----")
print(num)
print("-----test1-2-----")
def test2():
print("-----test2-1-----")
test1()
print("-----test2-2-----")
def test3():
try:
print("-----test3-1-----")
test1()
print("-----test3-2-----")
except Exception as result:
print('捕获到了异常,信息是:',result)
print("-----test3-3-----")
test3()
print("-----华丽的分割线-----")
test2()
assert语句
try:
assert 1 == 2, "1 is not equal 2!"
except AssertionError as reason:
print("%s:%s"%(reason.__class__.__name__, reason))
当判断表达式expression
为真时,什么都不做;如果表达式为假,则抛出AssertionError
异常
with…as语句
with...as
上下文管理语句的常用场景:
try:
f = open('d:\\test.txt')
for line in f:
print(line)
except IOError:
print('读写文件出错!')
else:
print('正常读写完毕!')
finally:
f.close()
上面的代码可以用with...as
语句(假设文件存在)很简单地解决
with open('d:\\test.txt') as f:
for line in f:
print(line)
with...as
会处理内部识别的异常,并做善后处理。而对于其它异常,在处理完善后操作后,仍然会抛出异常,所以外部仍然要使用try
:
try:
with open('d:\\test.txt') as f:
for line in f:
print(line)
except IOError:
print('读写文件出错!')
else:
print('正常读写完毕!')
抛出自定义异常
自定义异常
自定义的异常应时Error或Exception类的子类
class ShortInputException(Exception):
# 自定义的异常类。
def __int__(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleast
抛出异常
使用自定义的异常类,用raise抛出对应的异常
try:
s = input('请输入 --> ')
if len(s) < 3:
# raise 引发一个你定义的异常
raise ShortInputException(len(s), 3)
except ShortInputException as result: # x这个变量被绑定到了错误的实例
# print(result.atleast)
print('ShortInputException: 输入的长度是 %d,长度至少应是 %d'% \
(result.length, result.atleast))
else:
print('没有异常发生.')
raise…from语句
Python允许raise
语句拥有一个可选的from
子句
raise exception from otherexception
当使用from
的时候,第二个表达式指定了另一个异常类或实例,它会附加到引发异常的__cause__
属性。
try:
1/0
except Exception as E:
raise TypeError('Bad') from E
raise...from
有助于后续对异常的分析和排查。