最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python實現(xiàn)上下文管理器的示例代碼

 更新時間:2023年07月03日 09:30:18   作者:江湖十年  
這篇文章主要為大家詳細介紹了Python中實現(xiàn)上下文管理器的具體方法,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起了解一下

在 Web 開發(fā)中,我們經(jīng)常需要對資源進行操作,如從數(shù)據(jù)庫中讀取數(shù)據(jù)、日志文件的寫入等。這些都是常見的資源操作,而資源是有限的,所以當我們對資源操作完成以后就需要對其進行釋放。如果資源沒有得到釋放,當資源占用數(shù)達到了操作系統(tǒng)的限定數(shù),就會導致程序崩潰。

在文件操作過程中,為了保證文件操作完成后關閉文件資源,我們可能會寫出這樣的代碼:

try:
    f = open('demo.txt', 'w')
    f.write('hello')
finally:
    f.close()

這是一個典型的資源操作的例子,不過 Python 提供了 with 語句可以對以上代碼進行簡化:

with open('demo.txt', 'w') as f:
    f.write('hello')

可以看到,用 with 重寫過的代碼中并沒有顯式的調用 f.close() 方法來關閉文件,但當 with 代碼塊執(zhí)行完以后,文件還是會被正常關閉的。即使在調用 f.write() 時產(chǎn)生異常,文件同樣會被關閉。

這就是 with 語句的強大之處,它不僅可以簡化我們的代碼,并且能夠自動釋放資源。其實這就是所謂的 上下文管理器。能夠自動分配和釋放資源正是上下文管理器最強大的地方。

open 函數(shù)能夠通過 with 語句完成自動化的上下文管理,實際上,我們同樣可以實現(xiàn)自定義的 上下文管理器。Python 為我們實現(xiàn)自定義 上下文管理器 提供了一個統(tǒng)一的接口——上下文管理協(xié)議。只要我們按照 Python 的規(guī)定實現(xiàn)了 上下文管理協(xié)議,就能夠實現(xiàn)自定義的 上下文管理器。

基于類實現(xiàn)上下文管理器

我們知道,在 Python 中有很多雙下劃線開頭、雙下劃線結尾的方法,我們通常稱作 魔法方法?;陬惖纳舷挛墓芾砥骶褪峭ㄟ^ __enter__、__exit__ 兩個 魔法方法 來實現(xiàn)的。

下面通過一個自定義的文件上下文管理器類來介紹上下文管理器的實現(xiàn):

class MyFileManager(object):
    def __init__(self, filename, mode):
        print('call __init__')
        self.filename = filename
        self.mode = mode
        self.file = None
    def __enter__(self):
        print('call __enter__')
        self.file = open(self.filename, self.mode)
        return self.file
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('call __exit__')
        if self.file:
            self.file.close()
with MyFileManager('demo.txt', 'w') as f:
    print('write file')
    f.write('test')

代碼執(zhí)行結果如下:

call __init__
call __enter__
write file
call __exit__

可以看到,只需要十幾行的代碼,我們就實現(xiàn)了一個上下文管理器。而它的效果和 with open 并無兩樣。由代碼執(zhí)行結果我們可以分析出代碼的執(zhí)行順序。首先在 with 語句后面實例化 MyFileManager 類,實例化過程中會調用類的 __init__ 方法,接著自動調用了 __enter__ 方法并拿到返回值,即文件對象,as f 就是將 __enter__ 方法返回的文件對象賦值給 f 變量,然后執(zhí)行 with 代碼塊中的代碼對文件進行寫入,當程序將要退出 with 代碼塊時,就會自動調用 MyFileManager 類的 __exit__ 方法。

以上就是自定義 上下文管理器 的執(zhí)行邏輯。要實現(xiàn) 上下文管理器,__enter__、__exit__ 兩個方法是必須實現(xiàn)的。其中 __enter__ 方法用來獲取資源,所以它將在 with 語句代碼塊開始執(zhí)行之前被調用,__exit__ 方法用來釋放資源,它將在 with 語句代碼塊執(zhí)行結束將要退出時被調用。

需要額外注意的是 __exit__ 方法的參數(shù),相比 __enter__ 方法它多了三個參數(shù),這三個參數(shù)的作用分別是:

  • exc_type: 異常類型
  • exc_val: 異常的值
  • exc_tb:異常棧

當執(zhí)行 with 語句塊中的代碼,程序有可能會拋出異常,而 __exit__ 方法的這三個參數(shù),就會包含 with 語句塊中產(chǎn)生的異常信息。所以 __exit__ 方法還為我們提供了另外一個功能,即可以在此方法內(nèi)部對異常進行處理,由開發(fā)者來決定異常的處理方式。

class MyFileManager(object):
    def __init__(self, filename, mode):
        print('call __init__')
        self.filename = filename
        self.mode = mode
        self.file = None
    def __enter__(self):
        print('call __enter__')
        self.file = open(self.filename, self.mode)
        return self.file
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('call __exit__')
        if self.file:
            self.file.close()
        if exc_type:
            print(f'exc_type: {exc_type}')
            print(f'exc_val: {exc_val}')
            print(f'exc_tb: {exc_tb}')
            return True
with MyFileManager('demo.txt', 'w') as f:
    raise Exception('write error')

代碼執(zhí)行結果如下:

call __init__
call __enter__
call __exit__
exc_type: <class 'Exception'>
exc_val: write error
exc_tb: <traceback object at 0x036D08A0>

可以看到,在 with 代碼塊中拋出的異常已經(jīng)被 __exit__ 方法捕獲了。需要注意的是,在 __exit__ 方法內(nèi)部的最后還返回了 True,這代表異常已經(jīng)處理,而不需要繼續(xù)向上拋出,如果沒有返回 True,那么異常將繼續(xù)向上拋出,最終被 Python 解釋器捕獲到,繼而終止程序。

基于生成器實現(xiàn)上下文管理器

Python 還提供了另一種基于生成器來實現(xiàn) 上下文管理器 的方法。示例代碼如下:

from contextlib import contextmanager
@contextmanager
def my_file_manager(filename, mode):
    print('open file')
    f = open(filename, mode)
    yield f
    print('close file')
    f.close()
with my_file_manager('demo.txt', 'w') as f:
    print('write file')
    f.write('demo')

代碼執(zhí)行結果如下:

open file
write file
close file

基于生成器的 上下文管理器 可以讓我們不必通過類來實現(xiàn),只需要一個打上 @contextmanager 裝飾器的生成器函數(shù)即可。相比類實現(xiàn)的方式代碼更加簡潔,不過理解上來說沒有類實現(xiàn)的方式來的清晰。但這種風格寫起來更加 Pythonic。

其實 上下文管理器 的本質是能夠在我們需要執(zhí)行的一段代碼之前和之后分別執(zhí)行一段邏輯。這剛好能夠利用生成器函數(shù)的特性,在 yield 關鍵字之前執(zhí)行預處理工作,然后代碼執(zhí)行到 yield 處時讓出函數(shù)的控制權,這時候再執(zhí)行我們需要執(zhí)行的一段代碼邏輯,最后 with 語句幫我們把執(zhí)行控制權交回到生成器函數(shù)內(nèi)部,執(zhí)行一些清理工作。

最后,一個小知識點,一個 with 語句實際上可以同時處理多個上下文管理器。

with open('a.txt', 'w') as a, open('b.txt', 'w') as b:
    a.write('hello')
    b.write('world')

到此這篇關于Python實現(xiàn)上下文管理器的示例代碼的文章就介紹到這了,更多相關Python上下文管理器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Python腳本開發(fā)中的命令行參數(shù)及傳參示例詳解

    Python腳本開發(fā)中的命令行參數(shù)及傳參示例詳解

    這篇文章主要為大家介紹了Python腳本開發(fā)中的命令行參數(shù)及傳參示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • python在TXT文件中按照某一字符串取出該字符串所在的行方法

    python在TXT文件中按照某一字符串取出該字符串所在的行方法

    今天小編就為大家分享一篇python在TXT文件中按照某一字符串取出該字符串所在的行方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • 在Python中使用Fsolve函數(shù)的過程解析

    在Python中使用Fsolve函數(shù)的過程解析

    這篇文章主要介紹了在Python中使用Fsolve函數(shù)的過程解析,在這篇文章中,我們了解到fsolve?是用來尋找非線性方程的根的,了解到fsolve?可以接受的不同種類的參數(shù)以及每個參數(shù)的含義,需要的朋友可以參考下
    2023-06-06
  • 從Python程序中訪問Java類的簡單示例

    從Python程序中訪問Java類的簡單示例

    這篇文章主要介紹了從Python程序中訪問Java類的簡單示例,包括給出了在安卓開發(fā)中的一個短小示例,需要的朋友可以參考下
    2015-04-04
  • 關于python的list相關知識(推薦)

    關于python的list相關知識(推薦)

    下面小編就為大家?guī)硪黄P于python的list相關知識(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Python常見異常處理總結

    Python常見異常處理總結

    這篇文章主要介紹了Python常見異常處理總結,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-07-07
  • Python操作JSON文件的知識點整理

    Python操作JSON文件的知識點整理

    Python?提供了內(nèi)置的?json?模塊來處理?JSON?格式的文件。該模塊主要分為讀取和寫入?JSON?文件。本文主要為大家整理了一些Python操作JSON文件的知識點,需要的可以參考一下
    2023-01-01
  • Pycharm基本操作及調試代碼

    Pycharm基本操作及調試代碼

    最近天氣狂熱暴躁,很難靜下心來學習啦,于是給大家整理一些python開發(fā)工具pycharm基本操作及調試代碼吧,感興趣的朋友跟隨小編一起看看吧
    2021-06-06
  • python實現(xiàn)簡單中文詞頻統(tǒng)計示例

    python實現(xiàn)簡單中文詞頻統(tǒng)計示例

    本篇文章主要介紹了python實現(xiàn)簡單中文詞頻統(tǒng)計示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • python調用matlab的m自定義函數(shù)方法

    python調用matlab的m自定義函數(shù)方法

    今天小編就為大家分享一篇python調用matlab的m自定義函數(shù)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-02-02

最新評論

梓潼县| 逊克县| 吉林市| 定襄县| 河曲县| 万载县| 西峡县| 砚山县| 唐河县| 海南省| 东明县| 泾川县| 涟水县| 芦溪县| 泸溪县| 东乡族自治县| 祁连县| 张家界市| 武夷山市| 河南省| 琼结县| 淮北市| 嘉荫县| 乌鲁木齐县| 麻江县| 灵川县| 丹巴县| 奎屯市| 五河县| 亳州市| 嫩江县| 新源县| 安阳县| 灵山县| 博乐市| 胶南市| 汾西县| 融水| 长宁县| 教育| 疏附县|