程序在运行过程中,如果出错就不会执行出错语句后面的代码,导致程序异常中断,因此为了提高程序健壮性,容错性,对容易发生错误的语句需要捕获异常对异常处理,保证程序的连续性提高稳定性。
def func_1():
x = 10
y = 0
b = x/y
print(b)
print("做完除法后需要执行的代码")
Traceback (most recent call last):
File "/Users/fujinjie/PythonProjects/develop_test/buyer_app_autotest/unit_test.py", line 30, in <module>
r = func_1()
File "/Users/fujinjie/PythonProjects/develop_test/buyer_app_autotest/unit_test.py", line 26, in func_1
b = x/y
ZeroDivisionError: division by zero
由于y = 0 ,即除数为0,程序抛出:ZeroDivisionError: division by zero 的异常,b = x/y后面的代码并没有被继续执行,因为出错后程序是并不知道如何处理所以直接中断后续,并抛出错误告知用户,假设在我们自动化测试中,可能要执数百条用例,如果某一句子代码执行出现异常,则自动化程序就会异常中断无法继续执行测试。
一、try…except…错误处理机制
def func_1():
x = 10
y = 0
try:
b = x/y
print(b)
except: # except捕获所有类型的异常,即只要有异常就捕获,不区分异常类型
print("出现错误异常后,执行这里")
print("做完除法后需要执行的代码")
#出现错误异常后,执行这里
做完除法后需要执行的代码
上面是通过try…except 优化后的函数,把会出错的代码放入try: 语句下作为try的子句,当try下面的代码出错时,程序会执行except:下面的代码,并执行程序后续代码,如果try: 下面的代码没有出错,则跳过except: 直接执行后续代码,程序继续运行。
在这里通过except我们捕获try代码块中的错误和异常,相当于告诉程序,当try下面语句出错时,该如何处理,上面我们直接做了一个字符串的输出: “出现错误异常后,执行这里”
二、except + 异常类型 捕获指定类型的异常
def func_1():
x = 10
y = 0
try:
b = x/y
print(b)
except ZeroDivisionError as e: # as 为别名,当一个变量名称太长时可取别名代替简化
print(f"出错啦,错误信息:{e}")
print("做完除法后需要执行的代码")
出错啦,错误信息:division by zero
做完除法后需要执行的代码
通过traceback.format_exc()返回异常栈(返回是数据类型是字符串)
import traceback
def func_1():
x = 10
y = 0
try:
b = x/y
print(b)
except ZeroDivisionError as e: # as 为别名,当一个变量名称太长时可取别名代替简化
ei = traceback.format_exc()
print(f"出错啦,错误信息:{e},{ei}")
print("做完除法后需要执行的代码")
出错啦,错误信息:division by zero,Traceback (most recent call last):
File "C:\Users\37210\Desktop\Jcmall_study\test_b\b_3.py", line 8, in func_1
b = x/y
ZeroDivisionError: division by zero
做完除法后需要执行的代码
常见异常举例
IOError 输入/输出异常;基本上是无法打开文件
TypeError 传入对象类型与要求的不符合
AttributeError 无法访问该对象,一般对象不存在,比如foo.x,但是foo没有属性x
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下 标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,一般是语法错误
except 后面可以指定捕获的错误类型,错误类型指定后,如果try:下面的代码抛出的错误类型非该指定的类型,则不会被捕获,程序仍旧会异常终止;
def func_1():
x = 10
y = 0
try:
b = x/y
print(b)
except ValueError as e: # 这里对ValueError的异常进行捕获
print(f"出错啦,错误信息:{e}")
print("做完除法后需要执行的代码")
Traceback (most recent call last):
File "/Users/fujinjie/PythonProjects/develop_test/buyer_app_autotest/unit_test.py", line 33, in <module>
r = func_1()
File "/Users/fujinjie/PythonProjects/develop_test/buyer_app_autotest/unit_test.py", line 27, in func_1
b = x/y
ZeroDivisionError: division by zero
三、except 捕获多个指定的错误类型
def func_1():
x = 10
y = 0
try:
b = x/y
print(b)
except (TypeError,ValueError,ZeroDivisionError) as e: # 这里对 ZeroDivisionError的异常进行捕获
print(f"出错啦,错误信息:{e}")
print("做完除法后需要执行的代码")
出错啦,错误信息:division by zero
做完除法后需要执行的代码
def func_1():
x = 10
y = "0" # 此处y是一个str类型
try:
b = x/y
print(b)
except (TypeError,ValueError,ZeroDivisionError) as e: # 这里对 TypeError的异常进行捕获
print(f"出错啦,错误信息:{e}")
print("做完除法后需要执行的代码")
出错啦,错误信息:unsupported operand type(s) for /: 'int' and 'str'
做完除法后需要执行的代码
四、try…except…finally
不管try: 下面的语句是否报错异常,finally:下面的语句块始终会被执行
def func_1():
x = 10
y = 0
try:
b = x/y
print(b)
except: # except捕获所有类型的异常,即只要有异常就捕获,不区分异常类型
print("出现错误异常后,执行这里")
finally:
print("finally中代码始终会被执行")
print("做完除法后需要执行的代码")
出现错误异常后,执行这里
finally中代码始终会被执行
做完除法后需要执行的代码
def func_2():
x = 10
y = 1
try:
b = x/y
print(b)
except: # except捕获所有类型的异常,即只要有异常就捕获,不区分异常类型
print("出现错误异常后,执行这里")
finally:
print("finally中代码始终会被执行")
print("做完除法后需要执行的代码")
10.0
finally中代码始终会被执行
做完除法后需要执行的代码
try: 下面的代码未发生异常,则执行else: 下面的代码,如果发生异常则执行except: 下面的代码,因此esle: 代码块的执行与否,取决于try: 下面是否报异常;
def func_1():
x = 10
y = 1
try:
b = x/y
print(b)
except: # except捕获所有类型的异常,即只要有异常就捕获,不区分异常类型
print("出现错误异常后,执行这里")
else:
print("没有异常会执行这里的代码")
finally:
print("finally中代码始终会被执行")
print("做完除法后需要执行的代码")