python with拋出異常是什麼原理

今天做多GPU處理手寫數字識別的時候對with方法記得不是很清楚了

平常用的時候僅僅知道with相當於try…expect 拋出異常的作用

對於with來說,其底層的實現原理記憶的並不是很清晰


於是我自己做了一個小代碼進行測試,以下就是我定義的代碼

########################################################################
class A:
    #----------------------------------------------------------------------
    def __init__(self):
        self.a = 0
    #----------------------------------------------------------------------
    def __enter__(self):
        print("in enter")
    #----------------------------------------------------------------------
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("3 is not div 0")
        print("in exit")           
        
if __name__ == "__main__":
    a = A()
    with a :
        print("I'm here")
        print(3/0)
    print("helel")

不難發現,在執行with中的程序的時候會出現除0報錯的問題

但是with的整個流程是什麼樣的呢?

我們看看運行的結果:

控制檯的窗口打印的信息是:
在這裏插入圖片描述
從打印的流程中,我們不難看出

首先當程序運行到with的時候

會進入def __enter__(self):的方法中

其次會運行with方法中的程序,比如上面的I'm here

但是當運行到 3/0的時候,會發現出現異常了

會直接進入到__exit__的方法中,打印exit中的內容

最後拋出異常


我們再次假設,如果with中沒有異常,還會執行__exit__的方法麼? 答案:是的

我們稍微更改一下代碼

class A:

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        self.a = 0
    #----------------------------------------------------------------------
    def __enter__(self):
        print("in enter")
    #----------------------------------------------------------------------
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("3 is not div 0")
        print("in exit")           
        
if __name__ == "__main__":
    a = A()
    with a :
        print("I'm here")
        print("3/0")
    print("helel")

我們將3/0的代碼變成了字符串,這樣就不會報錯了

打印的結果如下所示:

in enter
I'm here
3/0
3 is not div 0
in exit
helel

通過打印的結果,我們可以得出一個結論就是:

with在執行的過程中,在with中的代碼,不論是否報錯都將會執行__enter____exit__函數

但是,當執行到問題程序的時候,會直接進入到__exit__函數中退出。

猜想基於以上的問題,我們似乎可以把with方法看做是一個線程鎖。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章