前幾篇文章寫的是關于Xlwings的相關知識,介紹了其相關API的使用方法,大家在使用Xlwing對Excel進行操作的時候,就可以使用推文中介紹的方法完成自己的任務。關于其與VBA的結合的使用,等后期遇到比較好項目的時候我再跟大家介紹。
從現在開始,將開啟新的寫作《Python實用教程系列》,主要是針對自己在項目中,對那些平時使用頻率較高的,覺得重要的知識點進行總結和歸納,以更好的幫助大家在寫代碼的時候起到舉一反三的作用,閑話不多說,這個系列的開篇我們就從-異常處理講起!
百度百科中對異常處理的介紹為:異常處理,是編程語言或計算機硬件里的一種機制,用于處理軟件或信息系統中出現的異常狀況(即超出程序正常執行流程的某些特殊條件)。從這個角度來看,異常處理是保證程序正常運行關鍵,因此異常處理是非常重要的!
在Python中,處理異常的基類是:BaseException,各個異常具體如下所示:
一、異常分類
基類BaseException中有一個異常類Warning,這個Warning我們應該遇見的次數很多了,比如我們在運行代碼的時候,比如某一個要模塊版本過低的時候會出現這樣的告警。
記下來我們來介紹上述所列的幾個常見異常:
1. AttributeError
class Car(): def __init__(self): self.car_lenth = 3.5 self.car_height = 1.7 self.car_name = 'Benz'new_car = Carprint(new_car.car_width)
上述代碼最后一行代碼試圖訪問不存在的屬性car_width,這將拋出一下的異常:
AttributeError: type object 'Car' has no attribute 'car_width'
2. IndexError
def len_list(number): print(number[len(number)] + 1)len_list([1,2,3,4,5])
上述代碼試圖訪問超出列表的索引進行取值,這將拋出異常:
IndexError: list index out of range
3. KeyError
def visit_dic(dic_num): print(dic_num['4'])dic_123 = {'1':'我', '2':'愛', '3':'python學堂'}visit_dic(dic_123['4'])
上述代碼試圖訪問字典dic_123中不存在的鍵值,這將拋出KeyError: '4'異常
4. NameError
def name_err(): print(name)name_err()
上述代碼中,函數name_err()中試圖打印不存在的name對象,將拋出異常:
NameError: name 'name' is not defined
5. OSError
def open_file(filename): file=open(filename)file = r'C:\Users\TEN\Desktop\'1.txt'open_file(file)
上述代碼試圖打開桌面一個不存在的文件1.txt,這將拋出OSError異常:
FileNotFoundError:[Errno2]No such file or directory:
"C:\Users\TEN\Desktop\'1.txt"
值的一提的是在python3.3版本以后,IOError(有關于輸入輸出的異常)將并到OSError中,看上述Xmind圖可知FileNotFoundError屬于OSError類。
6. SyntaxError
def syn_error(): print('python知識學堂') print('今天天氣好)syn_error()
上述代碼第二行的print打印測時候,少了一個“’”,將拋出異常:
SyntaxError: EOL while scanning string literal
7. TypeError
def add_number(parameter1, parameter2): sum = parameter1 + parameter2 return sumtotal = add_number(1, 2, 3)print(total)
上述代碼的函數add_number接受2個參數,第五行代碼傳入了3個參數,這將拋出類型錯誤的異常:
TypeError: add_number() takes 2 positional arguments but 3 were given
綜上,我們看了7種類型的異常。那么很顯然想到的就是,出現的這些異常我們該怎么處理呢?接下來我們就將介紹處理異常的一些方法:
二、Try-except
異常是使用try-except來進行處理的,使用try-except的好處就是可以讓python執行指定的操作,可以人為定義一些面向用戶友好的一些錯誤信息,幫助用戶定位錯誤。在實際的項目中,我們把可能出現異常的代碼塊放在try中,以便排除異常并保證其余代碼正常運行而不退出。
比如我們使用try-except處理一個ZeroDivisionError異常:
try: print(100/0)except ZeroDivisionError: print('分母不能為0')
這里出現錯誤的代碼被放在了try中,如果try中的代碼沒有問題,python將跳過except中的代碼;如果try中的代碼出現問題,則會執行except中的代碼。
這里有一個技巧,就是else模塊的使用,比如:
try: print(100/1)except ZeroDivisionError: print('分母不能為0')else: print('python')
上述代碼輸出:100.0,python。使用else的好處就是可以讓代碼繼續執行,即使遇到一些可能的錯誤,作為一種選擇性的繼續執行時非常nice的。
在拋出異常的時候,我們可以使用except error_type as errorname:的形式,那么使用print(errorname)就可以打印異常對象了,十分方便。
try: print(100/0)except ZeroDivisionError as zeror: print('分母不能為0') print(zeror)else: print('python')
三、多except
在實際的項目中,我們在一段代碼中需要處理的異常不只一個,比如要同時處理ArithmeticError和ValueError。ArithmeticError是ZeroDivisionError的父類,這個時候我們就可以使用多Try-except方法了,該方法就可以進行多重異常的捕獲了哦。
try: file = open(r'C:\Users\TEN\Desktop\1.txt') # 桌面不存在文件1.txt print(100/0) print(100/2)except ZeroDivisionError as zeror: print('分母不能為0')except FileNotFoundError as fn: print(fn) print('python')else: print('運行結束')
程序正常運行且上述代碼輸出:
[Errno 2] No such file or directory: "C:\Users\TEN\Desktop\'1.txt"
python
上述代碼使用多個except來進行不同的異常處理,大家可以好好研究一下其中的打印為什么是這樣。
四、嵌套Try-except
在實際的項目中我們可能還會遇到這樣的情況:在一個try-except中處理了一個異常,在這個異常處理之中我們還要進行異常的處理,此時就需要使用嵌套Try-except了,正好python中也是支持這個嵌套的。我們來看一個實際的例子,來感受一下:
def trying_test(): try: try: print(100/0) except: print('分母不能為0') try: file = open(r'C:\Users\TEN\Desktop\1.txt') except FileNotFoundError as fn: print(fn) except: print('python') finally: print('最后的打印')trying_test ()
上述代碼運行輸出:
分母不能為0
[Errno 2] No such file or directory: "C:\Users\TEN\Desktop\'1.txt"
最后的打印
上述兩個嵌套的try-except被嵌套在第一個代碼中,精確的說就是兩個try-except被放在try代碼塊中,當然了實際的開發中我們也可與將要被嵌套的try-except放在except的代碼塊中。Python的traceback提供了一個print_exc()函數可以幫助我們打印一些異常的信息,有興趣的小伙伴可以查閱一下相關的文檔。
有的小伙伴注意到上述中有一個finally,這個finally的一個好處就是在異常拋出的之后,這個finally總會執行的,比如在諸如打開文件、寫數據到文件的操作失敗的時候就可以進行關閉文件的操作。
五、With-as
我們在看其他人代碼的時候,會看到這樣的代碼:with open(filename) as f 的樣式。使用with語句的好處,就是到達語句末尾時,會自動關閉文件,這就不需要使用try-except的方式捕捉異常進行關閉文件的操作了。
如果直接使用open()方法打開文件,如果出現異常,如讀取過程中文件不存在或異常,則直接出現錯誤,close方法無法執行,文件無法關閉的,我們來看看使用with open…的方式:
def open_file(filename): try: with open(filename) as f: file = open(filename) print('文件名:',file.name) except OSError as E: print('open file error')filename = r'C:\Users\TEN\Desktop\1.txt'open_file(filename)
六、異常類的定義
在實際的工程項目中,我們有時候需要定義一個區別于系統的異常類,還好python提供了一個可以自己定義異常類的方法,我們來看下面的代碼:
# 自定義異常類,繼承于Exception基類class Division_Error(Exception): # 當輸出有誤時,拋出此異常 # 初始化 def __init__(self, value, name): self.value = value self.name = name # 返回異常類對象的相關信息 def __str__(self): if self.value % 2 != 0 and len(self.name) < 5: return ("{}不是偶數,{}長度小于4".format(self.value,self.name) )try: # 拋出異常 print('嘗試顯示拋出異常') diverr = Division_Error(1,'name') raise diverr #或raise Division_Error(1,'name')'except Division_Error as diverr: print('diverr: {}'.format(diverr))
上述代碼中自定了一個繼承于基類的Division_Error類,用于拋出一些異常,在try的代碼塊中,我們使用raise用于顯示的拋出異常。
七、總結
上述就是Python中異常處理的相關知識了,介紹了python中幾個異常的類型以及使用小例子具體介紹了他們的用法,接著我們介紹了異常的處理方法,這些方法在實際的項目中都非常的實用,小伙伴們可以參考其中的一些介紹進行實際的操作。