Python之try except异常处理工作机制和案例解析

【说明】我们在写python程序时往往为了考虑程序的健壮性通常会考虑到程序执行过程中遇到什么样的异常,出现这样的错误代表着什么,我们可以提前捕获这些个错误方便我们进行处理,python在实际应用中通过try与except来实现异常的处理:
python中try/except/else/finally语句的完整格式如下所示:
(ps:测试代码为Python3.7.4)

try:
     Normal execution block
except A:
     Exception A handle
except B:
     Exception B handle
except:
     Other exception handle
else:
     if no exception,get here
finally:
     print("finally")  

语句逻辑意义:
在这里插入图片描述
说明:
正常执行的程序在try下面的Normal execution block执行块中执行,在执行过程中如果发生了异常,则中断当前在Normal execution block中的执行跳转到对应的异常处理块中开始执行;
python从第一个except X处开始查找:
如果找到了对应的exception类型则进入其提供的exception handle中进行处理,
如果没有找到则直接进入except块处进行处理。
except块是可选项,如果没有提供,该exception将会被提交给python进行默认处理,处理方式则是终止应用程序并打印提示信息;

如果在Normal execution block执行块中执行过程中没有发生任何异常,则在执行完Normal execution block后会进入else执行块中(如果存在的话)执行。
无论是否发生了异常,只要提供了finally语句,以上try/except/else/finally代码块执行的最后一步总是执行finally所对应的代码块。

ATTENTION PLEASE:
1.在上面所示的完整语句中try/except/else/finally所出现的顺序必须是try–>except X–>except–>else–>finally,即所有的except必须在else和finally之前,else(如果有的话)必须在finally之前,而except X必须在except之前。否则会出现语法错误。
2.对于上面所展示的try/except完整格式而言,else和finally都是可选的,而不是必须的,但是如果存在的话else必须在finally之前,finally(如果存在的话)必须在整个语句的最后位置。
3.在上面的完整语句中,else语句的存在必须以except X或者except语句为前提,如果在没有except语句的try block中使用else语句会引发语法错误。也就是说else不能与try/finally配合使用。

【try-except处理常见异常分类】

  • 单个异常处理
    -语句:
try:
    statements   #处理的语句
except  Error1 as e:   #遇到Error1执行下面的语句,在python2中写成except  Error1,e
    print(e)

eg1:

try:
   db = pyodbc.connect(r'DRIVER={SQL Server Native Client 10.0};'r'SERVER=(local);'r'DATABASE=test;UID=ssa;PWD=726803')
except pyodbc.InterfaceError as err: #抓取pyodbc.InterfaceError这个异常大类中的错误信息种类并打印
   print(err)#err是错误的详细信息   
#输出
('28000', "[28000] [Microsoft][SQL Server Native Client 10.0][SQL Server]用户 'ssa' 登录失败。 (18456) (SQLDriverConnect); [28000] [Microsoft][SQL Server Native Client 10.0][SQL Server]用户 'ssa' 登录失败。 (18456)")
  • 处理多个异常
    -语句:
方式1:
try:
    code
except Error1 as e:  #处理Error1异常
    print(e)
except Error2 as e:   #处理Error2异常
    print(e)
    
方式2:
try:
    code
except (Error1,Error2,...) as e:
    print(e)

注:第二种写法的用处:括号里面的所有错误,不管出现里面任何一种错误都用统一的处理方法。
eg2:

name = [1,2,3]
data = {"a":"b"}
try:
    data["c"]   # 这边已经出现异常KeyError ,所以直接跳出code,跳到KeyError 下去处理
    name[3]
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
  
#输出
'c'

【Exception实现所有异常处理】

-语句:

try:
    code
except (Error1,Error2,...) as e:
    print(e)
except Exception as e:  
    print(e)
    # 说明 用Exception表示一下子抓住所有异常,这个一般情况下建议在异常最后面用,用在最后抓未知的异常

eg3:

try:
    open("qigao.text","r",encoding="utf-8")
except (IndexError,KeyError) as e:   #没有IndexError,KeyError这两个异常
    print(e)
except Exception as e: 
    print(e)
  # 没有IndexError,KeyError这两个异常只能通过 Exception 这个异常处理,来抓住所有的异常
#输出
[Errno 2] No such file or directory: 'qigao.text'

【else没有异常发生,执行else部分的codes】

try:
    print("A")    #代码没有异常
except (IndexError,KeyError) as e:
    print(e)
except Exception as e:
    print(e)
else:             #没有异常出错,走else的逻辑代码
    print("没有异常")
  
#输出
A
没有异常

【finnally最后执行】

try:
    code
except (Error1,Error2,...) as e:
    print(e)
except Exception as e:
    print(e)
else:
    print("没有错误,执行")
finnally:
    print("不管有没有错,都执行finnally")
  • 无异常情况
try:
    print("A")  #没有异常
except (IndexError,KeyError) as e:
    print(e)
except Exception as e:
    print(e)
else:
    print("没有异常")
finally:
    print("不管有没有错,都这行finnally")
#输出
A
没有异常
不管有没有错,都这行finnally 
  • 有异常情况
try:
    data = {"a":"b"}
    data["c"]   #data字典中没有'c'这个key值
except (IndexError,KeyError) as e:
    print(e)
except Exception as e:
    print(e)
else:
    print("没有异常")
finally:
    print("不管有没有错,都这行finnally")
#输出
'c'
不管有没有错,都这行finnally   

【 自定义异常】

  • 定义异常类
class MyError(Exception):  #定义一个异常类MyError,继承Exception
  
    def __init__(self,message):
        self.message = message
  
    def __str__(self):
        return self.message #给对象取一个名
  • 触发自定义异常
    我们可以使用raise语句自己触发异常
    raise语法格式如下:
     raise [Exception [, args [, traceback]]]

语句中 Exception 是异常的类型(例如,NameError)参数标准异常中任一种,args 是自已提供的异常参数。最后一个参数是可选的(在实践中很少使用),如果存在,是跟踪异常对象。

try:
    raise MyError("数据库未成功连接")           #触发自定义异常,MyError("数据库未成功连接")这个对象
except MyError as e:
    print(e)
  
#输出
数据库未成功连接

【写在后面】
说了这么多若果您还没看太懂那就直接自己试一下这个案例吧

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import xlsxwriter
import xlrd

workbook = xlsxwriter.Workbook('C:\\Users\\Elink 001\\Desktop\\tabletest.xls')
worksheet = workbook.add_worksheet('table')
workbook.close()

workbook1 = xlrd.open_workbook(r'C:\Users\Elink 001\Desktop\tabletest.xls')
sh = workbook1.sheet_by_name('table')

rows = sh.row_values(1)  # 第2行内容
cols = sh.col_values(0)  # 第1列内容
print("cols, rows", cols, rows)

# 获取单元格内容
print(" 第1行第1列数据", sh.cell(0, 0).value)  
  • step1:当我们执行以上代码后会生成一个表格
    手动添加以下数据:(1列3行,python默认row索引为0-2,col索引为0)
    在这里插入图片描述
    在上述代码后添加一行:
    print(" 第4行第1列数据", sh.cell(3, 0).value) #(显然这个cell的数据并不存在)

执行后Python提示:
IndexError: list index out of range

  • step2.加入try-except
#!/usr/bin/python3
# -*- coding: utf-8 -*-

import xlsxwriter
import xlrd

# workbook = xlsxwriter.Workbook('C:\\Users\\Elink 001\\Desktop\\tabletest.xls')
# worksheet = workbook.add_worksheet('table')
# workbook.close()

workbook1 = xlrd.open_workbook(r'C:\Users\Elink 001\Desktop\tabletest.xls')
sh = workbook1.sheet_by_name('table')

rows = sh.row_values(1)  # 第2行内容
cols = sh.col_values(0)  # 第1列内容
print("cols, rows", cols, rows)

# 获取单元格内容
print("第1行第1列数据", sh.cell(0, 0).value)  # 第1行第1列数据

i = 2
k = 0

try:
    test1 = sh.cell(0, 3).value
    if i > 1:
        k = 1
except IndexError:

    print("array index out of range")
    print("第1行第1列数据", sh.cell(0, 0).value)

j = 2

print("j = ", j)
print("k = ", k)

实验结果:
在这里插入图片描述
说明:
我认为try-except 的学习好比C语言中的if-else语法结构。即当我们将对于可能出错的代码放在try包含的内容中执行,如果发生错误,系统制动检测except中是否有设置好的错误分类,如果try执行结果的错误类型属于except错误类型,则执行except块语句,执行完之后再执行整个try-except之后的语句块:
本例中

i = 2
k = 0

try:
    test1 = sh.cell(0, 3).value
    if i > 1:
        k = 1
except IndexError:

    print("array index out of range")
    print("第1行第1列数据", sh.cell(0, 0).value)

j = 2

print("j = ", j)
print("k = ", k)
  • 当我们code执行到try:之后检测到 sh.cell(0, 3).value值并不存在, (k = 1没有执行,k仍然保持k = 0)
  • code自动跳转到except中,
  • except包含的错误类“IndexError”刚好包含try语句执行的错误类型“IndexError:list index out of range”,
  • 所以执行except中的两个print语句,并对K重新赋值为2
  • 接着执行try-except之后的语句

对于此处try-except的学习分享有任何不准确的地方希望大家多多交流,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时间之里

好东西就应该拿出来大家共享

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值