try…finally与嵌套及自定义异常抛出
try...finally...
try...finally...語句用來表達這樣的情況:在程序中,如果一個段代碼必須要執行,即無論異常是否產生都要執行,那么此時就需要使用finally。 比如文件關閉,釋放鎖,把數據庫連接返還給連接池等。
| try: ??? f = open("log.txt","r") ??? a = 10 ??? b = 0 ??? ret = a / b ? #捕獲多個類型的異常 except IOError as ex: ??? print(ex) except ZeroDivisionError as ex: ??? print(ex) else: ??? print("沒有異常,真是happy!") finally: ??? print("無論是否異常發生,都會執行!") |
?
| import time try: ??? f = open('log.txt') ??? try: ??????? while True: ??????????? content = f.readline() ??????????? if len(content) == 0: ??????????????? break ??????????? time.sleep(2) ??????????? print(content) ??? except KeyboardInterrupt: ??????? #如果在讀取文件的過程中,產生了異常,那么就會捕獲到 ??????? #比如按下了 ctrl+c ??????? print("捕獲到了以外終止異常!") ??? finally: ??????? f.close() ??????? print('關閉文件') except: ??? print("沒有這個文件") |
?
test.txt文件中每一行數據打印,但是我有意在每打印一行之前用time.sleep方法暫停2秒鐘。這樣做的原因是讓程序運行得慢一些。在程序運行的時候,按Ctrl+c中斷(取消)程序。
我們可以觀察到KeyboardInterrupt異常被觸發,程序退出。但是在程序退出之前,finally從句仍然被執行,把文件關閉。
?
?try嵌套
| import time try: ??? f = open('log.txt') ??? try: ??????? while True: ??????????? content = f.readline() ??????????? if len(content) == 0: ??????????????? break ??????????? time.sleep(2) ??????????? print(content) ??? finally: ??????? f.close() ??????? print('關閉文件') except: ??? print("沒有這個文件") |
?
函數嵌套調用中:
| def myDiv(a, b): ??? return a / b ? def test2(): ??? a = 10 ??? b = 0 ??? try: ??????? ret = myDiv(a, b) ??? except: ??????? print("test02已經捕獲到了異常,但是不想處理!") ??????? #手動上拋異常 ??????? raise ? def test3(): ??? try: ??????? test2() ??? except Exception as ex: ??????? print(ex) ? #myDiv函數拋出異常 #test02沒有處理,異常自動上拋 #test03接收到異常,并處理 #也就是說,異常是跨函數的 test3() |
?總結:
- 如果try嵌套,那么如果里面的try沒有捕獲到這個異常,那么外面的try會接收到這個異常,然后進行處理,如果外邊的try依然沒有捕獲到,那么再進行傳遞。
- 如果一個異常是在一個函數中產生的,例如函數A---->函數B---->函數C,而異常是在函數C中產生的,那么如果函數C中沒有對這個異常進行處理,那么這個異常會傳遞到函數B中,如果函數B有異常處理那么就會按照函數B的處理方式進行執行;如果函數B也沒有異常處理,那么這個異常會繼續傳遞,以此類推。。。如果所有的函數都沒有處理,那么此時就會進行異常的默認處理,即通常見到的那樣。
- 注意觀察上圖中,當調用test3函數時,在test1函數內部產生了異常,此異常被傳遞到test3函數中完成了異常處理,而當異常處理完后,并沒有返回到函數test1中進行執行,而是在函數test3中繼續執行。
?自定義異常拋出
你可以用raise語句來引發一個異常。異常/錯誤對象必須有一個名字,且它們應是Error或Exception類的子類。
下面是一個引發異常的例子:
| #自定義異常類 class OutOfRangeException(Exception): ??? def __init__(self,errMsg): ??????? self.msg = errMsg ? ??? def __str__(self): ??????? return self.msg ? ? class Person(object): ??? def __init__(self): ??????? self.name = None ??????? self.age = None ? ??? def setAge(self,age): ??????? if age < 0 or age > 100: ??????????? raise? OutOfRangeException("年齡應該在0-100之間!") ??????? self.age = age ? ??? def setName(self,name): ??????? self.name = name ? ??? def __str__(self): ??????? return "name:{} age:{}".format(self.name,self.age) ? if __name__ == "__main__": ??? person = Person() ??? person.setName("Edward") ??? person.setAge(80) ??? print(person) try: ??? person.setAge(101) except OutOfRangeException as ex: ??? print(ex) |
總結
以上是生活随笔為你收集整理的try…finally与嵌套及自定义异常抛出的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中随机输入数字再排序
- 下一篇: java中对象作为参数_java中对象引