91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python中的上下文管理器原理是什么

發布時間:2023-03-11 15:44:47 來源:億速云 閱讀:92 作者:iii 欄目:開發技術

這篇“Python中的上下文管理器原理是什么”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Python中的上下文管理器原理是什么”文章吧。

with語句

在我們日常使用場景中,經常會操作一些資源,比如文件對象、數據庫連接、Socket連接等,資源操作完了之后,不管操作的成功與否,最重要的事情就是關閉該資源,否則資源打開太多而沒有關閉,程序會報錯,以文件操作為例,通常我們會這樣寫:

f = open('file.txt', 'w')
try:
    f.write("Hello")
finally:
    f.close()

但既然close方法是必須的操作,那就沒必要顯式地調用,所以Python給我們提供了一種更優雅的方式,使用with語句:

with open('file.txt', 'w') as f:
    f.write("Hello")

在退出with語句下的代碼塊之后,f 對象會自動執行自己的close方法,實現資源的釋放,簡潔優雅。

上下文管理器原理

上下文管理器實際是內部實現了__enter__和__exit__方法的對象。

當我們使用with語法時:

__enter__()方法:返回一個值,可以將它賦值給as后面的對象,例如上面的中的f;

__exit__()方法:with語句退出或者發送異常時會執行這個方法。

1、__enter__方法說明

上下文管理器的__enter__方法是可以帶返回值的,默認返回None,這個返回值通過with…as…中的 as 賦給它后面的那個變量,所以 with EXPR as VAR 就是將EXPR對象__enter__方法的返回值賦給 VAR。

當然with...as...并非固定組合,單獨使用with...也是可以的,上下文管理器的__enter__方法還是正常執行,只是這個返回值并沒有賦給一個變量,with下面的代碼塊也不能使用這個返回值。

2、__exit__方法說明

上下文管理器的__exit__方法接收3個參數exc_type、exc_val、exc_tb,如果代碼塊BLOCK發生了異常e并退出,這3個參數分別為type(e)、str(e)、e.__traceback__,否則都為None。

同樣__exit__方法也是可以帶返回值的,這個返回值應該是一個布爾類型True或False,默認為None(即False)。如果為False,異常會被拋出,用戶需要進行異常處理。如果為True,則表示忽略該異常。

一個上下文管理器一般使用如下:

with EXPR as VAR:
    BLOCK

上述代碼的執行過程等價于:

ContextManager = EXPR
VAR = ContextManager.__enter__()
try:
    BLOCK
finally:
    ContextManager.__exit__()

f 對象就是把自己的close方法定義在了它的__exit__方法內部,實現了代碼塊BLOCK執行完之后自動關閉自身。

自定義上下文管理器

下面我們定義一個文件類,內部實現了__enter__和__exit__兩個方法:

class File:
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode

    def __enter__(self):
        print("進入")
        self.f = open(self.filename, self.mode)
        return self.f

    def __exit__(self, exc_type=None, exc_val=None, exc_tbs=None):
        print("退出")
        self.f.close()

這時候File類就是一個上下文管理器

我們分別通過 with語句 和 try/finally語句 使用File類對文件進行寫入操作

通過with語句執行:

with File('file.txt', 'w') as f:
    print("正在寫入...")
    f.write('Hello')

控制臺輸出:

進入
正在寫入...
退出

并得到了一個寫了 Hello 的 file.txt 文件

通過try/finally語句執行:

ContextManager = File('file.txt', 'w')
VAR = ContextManager .__enter__()
try:
    print("正在寫入...")
    VAR.write('Hello')
finally:
    ContextManager.__exit__()

控制臺輸出:

進入
正在寫入...
退出

并得到了一個寫了 Hello 的 file.txt 文件

兩者輸出一致,所以驗證了二中執行過程的等價關系是正確的。

contextmanager 裝飾器

Python還提供了一個contextmanager裝飾器,允許用戶將一個生成器定義為上下文管理器,該裝飾器將生成器中的代碼通過yield語句分成兩部分,yield之前的代碼為__enter__方法,yield之后的代碼為__exit__方法,yield的返回值即__enter__方法的返回值,用于賦給as后的變量。

下面我們通過contextmanager裝飾器也實現一個關于文件的上下文管理器:

from contextlib import contextmanager

@contextmanager
def open_file(filename, mode):
    print('進入')
    f = open(filename, mode)
    try:
        yield f
    finally:
        print('退出')
        f.close()

說明:這里使用 try/finally 是確保yield的過程中就算出現異常,文件也能正常關閉,當然這里也能處理異常,使用 try/except/finally 即可。

通過with語句執行:

with open_file('file.txt', 'w') as f:
    print("正在寫入...")
    f.write('Hello')

執行結果跟之前的上下文管理器執行結果一致,說明contextmanager裝飾器也能定義一個上下文管理器。

以上就是關于“Python中的上下文管理器原理是什么”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

沛县| 罗平县| 盐津县| 华容县| 北宁市| 清河县| 鄂伦春自治旗| 遵化市| 庄河市| 信宜市| 蒲江县| 磐石市| 天津市| 修文县| 黄浦区| 佛坪县| 北安市| 五华县| 普兰县| 黑龙江省| 武威市| 拜泉县| 泗洪县| 广丰县| 双流县| 邛崃市| 正宁县| 临潭县| 略阳县| 陆良县| 阳新县| 红安县| 湛江市| 荥阳市| 五莲县| 文成县| 馆陶县| 防城港市| 瑞昌市| 农安县| 六盘水市|