天天看點

python3: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文法的一種簡化,并且提供了對于異常非常好的處理方式。

根據實際需要應用在不同的場景。