目录
7.使用try...except...else...finally
异常捕获与处理
异常的概念
异常是指程序中的例外,影响程序正常执行的情况。
异常机制是指程序出现错误后,程序的处理方法。当出现错误后,程序的执行流程发生改变,程序的控制权转移到异常处理。如果程序执行过程中发生了异常,我们没有进行异常处理,那么程序就会中止执行下面的代码。但是如果我们进行了异常处理,程序会继续执行下面的代码
异常抛出机制
1.如果在运行时发生异常,解释器会查找相应的处理语句
2.要是在当前函数里没有找到,会将异常传递给上层的调用函数,看是否能处理
3.如果在最外层没有找到的话,停止运行,同时打印出traceback以便用户找到错误产生的原因
检测和处理异常
异常可以通过 try 语句来检测. 任何在 try 语句块里的代码都会被监测, 检查有无异常发
生。
1.使用try...except处理异常
#代码示例1:
try:
1/0
except ZeroDivisionError:
print ("divison not is zero")
#代码示例2:
try:
num=int("1.3")
except ValueError:
print ("Input error!")
2.使用嵌套处理异常
try:
try:
int("1.1")
except:
print("第二层try的异常出现了")
1/0
except:
print ("第一层try的异常出现了")
#执行后输出结果为:
第二层try的异常出现了
第一层try的异常出现了
3.使用带有多个except的try语句
def safe_float(obj):
try:
num=float(obj)
except ValueError:
print ("could not convert string to float!")
except TypeError:
print ("float() argument must be a string or a number")
else:
print (num)
safe_float([]) #输出结果:float() argument must be a string or a number
safe_float("abc") #输出结果:float() argument must be a string or a number
safe_float(1.1) #输出结果:1.1
4.使用异常参数和多个异常
1.except 语句在处理多个异常时要求异常被放在一个元组里;
2.except 使用异常参数作为输出的异常信息参数,来获取异常信息。并且异常参数中包含有异常信息、错误数字、错误位置等属性;
def safe_float(obj):
try:
num=float(obj)
except (ValueError,TypeError) as e:
#except (ValueError,TypeError),e: #py2中的格式
print (e)
#print (e.args)
print (e.__class__)
else:
print (num)
safe_float([])
#执行后输出结果为:
float() argument must be a string or a number, not 'list'
<class 'TypeError'>
5.使用try...except...else处理异常
当触发异常时,不执行else后面的语句块;当没有触发异常时才会执行
1.触发异常时,不执行else语句块(此时文件不存在):
try:
fp=open("reapalTest.txt")
except FileNotFoundError:
print ("File does not exist!")
else:
fp.close()
print ("成功打开文件")
#执行后输出结果:File does not exist!
2.不触发异常时,执行else语句块(此时文件已经存在);
try:
fp=open("reapalTest.txt")
except FileNotFoundError:
print ("File does not exist!")
else:
fp.close()
print ("成功打开文件")
#执行后输出结果:成功打开文件
6.使用try...finally处理异常
不管异常会不会发生,都会执行finally后面的语句块,一般用于文件关闭,释放锁等。
#同时使用嵌套异常
try:
try:
fp=open("test.txt","r",encoding="utf-8")
content=fp.readlines()
finally:
fp.close()
print ("文件已关闭")
except UnicodeDecodeError:
print ("打开文件编码格式错误")
#执行后输出结果为:
文件已关闭
打开文件编码格式错误
7.使用try...except...else...finally
没有异常时执行顺序: try->else->finally;
有异常时执行顺序: try->expect->finally;
#代码示例:
try:
fp=open("test.txt")
num=int(fp.read())
except Exception as e:
print ("error:",e)
else:
print (num)
finally:
try:
fp.close()
except Exception as e1:
print ("error:",e1)
8.捕获所有异常
需要注意的是:避免把大片的代码装入 try-except 中然后使用 pass 忽略掉错误. 你可以捕获特定的异常并忽略它们, 或是捕获所有异常并采取特定的动作。不要捕获所有异常,然后忽略掉它们。
def safe_float(obj):
try:
num=float(obj)
except:
print ("转化类型错误")
else:
print (num)
safe_float([])
#输出结果为:
转化类型错误
自定义异常
通过创建一个新的异常类,程序可以创建它们自己特定的异常。自定义异常都需要继承异常基类(Exception类),当然也可以继承具体的异常类(比如RuntimeError)
#代码示例1
class NetWorkError(RuntimeError):
#重写默认的__init__()方法
#抛出特定的异常信息
def __init__(self,value):
self.value=value
try:
raise NetWorkError("Bad hostname")
except NetWorkError as e:
print ("My exception occurred,value:",e.value)
#运行结果为:
My exception occurred,value: Bad hostname
#代码示例2
class ShortInputException(Exception):
def __init__(self,length,atleast):
Exception.__init__(self)
self.length=length
self.atleast=atleast
try:
s=input("Enter somthing:")
if len(s)<3:
raise ShortInputException(len(s),3)
except ShortInputException as e:
print ("ShortInputException:The input was of length %d,was expecting at least %d" % (e.length,e.atleast))
else:
print ("No exception was occured!")
#运行结果为:
Enter somthing:12
ShortInputException:The input was of length 2,was expecting at least 3
#代码示例3:
class testError(Exception):
def __init__(self,value):
self.value=value
try:
a=1
raise testError("变量a不能赋值为数字类型")
except testError as e:
print (e.value)
#运行结果为:
变量a不能赋值为数字类型
触发异常
raise关键字手动触发
使用关键字raise来触发异常,后面跟异常的名称。一旦执行raise语句,程序就会被终止
#代码示例1:
def exceptionTest(num):
try:
if num<0:
raise Exception("Invalid num")
elif num==0:
raise ZeroDivisionError("integer division or modulo by zero!")
except Exception as e:
print (e)
else:
print (num)
#调用函数,触发异常
exceptionTest(-2)
exceptionTest(0)
exceptionTest(2)
#运行结果为:
Invalid num
integer division or modulo by zero!
2
#代码示例2:
import sys
try:
a=int(sys.argv[1])
b=int(sys.argv[2])
if b==0:
raise Exception("除数不能为0")
except Exception as e:
print (e)
else:
print ("可以做除法运算,结果为%s" % (a/b))
assert语句触发异常
assert语句根据后面的表达式的真假来控制程序流。若为True,则往下执行。若为False,则中断程序并调用默认的异常处理器,同时输出指定的提示信息。
#代码示例:
try:
assert 1==0,"1不等于0"
except Exception as e:
print ("%s:%s" % (e.__class__.__name__,e))
#运行结果为:
AssertionError:1不等于0
使用traceback
print_exc()获取异常信息,并直接打印出来;
print_exc()还可以接受file参数直接写入到一个文件;
format_exc()也是获取异常信息,不过是字符串类型,需要print才可打印出来;
traceback.print_exc()与print (traceback.format_exc()) 效果是一样的
import traceback
def add(x,y):
return x+y
try:
add(1,)
except Exception:
traceback.print_exc()
#print (traceback.format_exc())
#traceback.print_exc(file=open("test.txt","w+")) #将错误信息写入到test.txt文件中
#运行结果为:
Traceback (most recent call last):
File "testyu.py", line 10, in <module>
add(1,)
TypeError: add() missing 1 required positional argument: 'y'