1. 程式人生 > >Python 異常處理以及with 語句的使用

Python 異常處理以及with 語句的使用

try …except…else 語句

是處理異常公式, try 是有可能拋異常的程式碼塊, except 抓取異常的型別, else 是指當沒有抓到拋錯,就執行這塊程式碼。請看下下邊的例子:

try:
    print("抓取的有可能的程式碼塊")
    raise IOError
except IOError as e:
    print("except  IOError")
except OSError as e:
    print("except OSError")
else:
    print("other erro")

finally:
    print("i am  finally")
#列印結果:
抓取的有可能的程式碼塊
except  IOError
i am  finally

從結果來看 走的路線是: try(按照raise 的error 找except)>找到except並執行except程式碼塊>執行finally語句塊 如果沒有拋錯走的路線是: try 沒有error>走else 語句>finally 看來不管有沒有錯誤, finally 語句一定會執行到。 在用到finally 要注意他會覆蓋 except or else 的返回值。

def try_list():
    try:
        print("抓取的有可能的程式碼塊")

        raise OSError
        return  1

    except IOError as e:
        print("except  IOError")
        return 2
    except OSError as e:
        print("except OSError")
        return 3
    else:
        print("other erro")
        return 4

    finally:
        print("i am  finally")
        return 5

print(try_list())
#列印結果

抓取的有可能的程式碼塊
except  IOError
i am  finally
5

從列印的結果 ,他覆蓋了 return 3。 如果走else路線同樣return 的4 也會被覆蓋, 自己試試下。 那小夥伴有疑問 什麼情況下使用 finally 呢 答案: 是在釋放資源的時候, 看下邊的例子。

def try_list():
    try:
        fp=open("Test。txt")
        raise OSError
        fp.close()
    except IOError as e:
        fp.close()
    except OSError as e:
        fp.close()
        print("except OSError")
    else:
        print("other erro")
        fp.close()

大家看了 嗎, 只要有流程的分支的地方一定要加上這個 fp.close(), 如果再加分支,還需要再加這個close 函式。 有沒有更好的解決方法嗎? 答案就是 用finally。請看下邊的程式碼:

def try_list():
    try:
        fp=open("Test。txt")
        raise OSError      
    except IOError as e:      
    except OSError as e:    
        print("except OSError")
    else:
        print("other erro")
    finally:
        fp.close()

大家看看是不是很神奇, 資源的釋放不光是檔案的關閉,還有socket 連線,資料庫的連線

上邊的內容只是複習下異常處理的內容, 下邊才是重頭戲 with上下文管理器

with上下文管理器

with上下文管理器協議包括兩個魔法函式 1.__enter__2.exit 用例項來解釋下這兩個魔法函式

class Person:
    def __enter__(self):    #獲取資源
        print("enter")
    def __exit__(self, exc_type, exc_val, exc_tb):   #釋放資源
        print("exit")
    def said(self):
        print("said")
        
 with Person() as P:
   P.said()

列印結果是: enter Traceback (most recent call last): exit File “C:/Users/tengfei/PycharmProjects/test1/alert.py”, line 12, in P.said() AttributeError: ‘NoneType’ object has no attribute ‘said’

根據提示我們就知道了, 我們例項化是“NoneType” 型別,意思就是空的物件。

原因是 因為我們在獲取資源(enter)沒有返回值,所以預設返回的是空。 我們加上 返回值 就可以執行成功瞭如下:

class Person:
    def __enter__(self):  #並沒有呼叫,也會執行這個函式
        print("enter")  
       # return  self

    def __exit__(self, exc_type, exc_val, exc_tb):   #並沒有呼叫,也會執行這個函式
        print("exit")
    def said(self):
        print("said")

with Person() as P:
    P.said()

列印結果: enter #並沒有呼叫,也會執行這個函式 said exit #並沒有呼叫,也會執行這個函式

總結: 上下文管理器協議 是用with 進行呼叫,預設呼叫了 enter 和 exit 兩個魔法函式。 with是對try…expect…finally語法的一種簡化,並且提供了對於異常非常好的處理方式。 根據實際需要應用在不同的場景。