亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

在 Web 開發(fā)中,我們經常需要對資源進行操作,如從數(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() 時產生異常,文件同樣會被關閉。

這就是 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 語句塊中產生的異常信息。所以 __exit__ 方法還為我們提供了另外一個功能,即可以在此方法內部對異常進行處理,由開發(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 代碼塊中拋出的異常已經被 __exit__ 方法捕獲了。需要注意的是,在 __exit__ 方法內部的最后還返回了 True,這代表異常已經處理,而不需要繼續(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ù)內部,執(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上下文管理器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳談tensorflow gfile文件的用法

    詳談tensorflow gfile文件的用法

    今天小編就為大家分享一篇詳談tensorflow gfile文件的用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • python爬蟲MeterSphere平臺執(zhí)行報告使用實戰(zhàn)

    python爬蟲MeterSphere平臺執(zhí)行報告使用實戰(zhàn)

    這篇文章主要為大家介紹了python爬蟲MeterSphere平臺執(zhí)行報告使用實戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • 解決Python print輸出不換行沒空格的問題

    解決Python print輸出不換行沒空格的問題

    今天小編就為大家分享一篇解決Python print輸出不換行沒空格的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • python友情鏈接檢查方法

    python友情鏈接檢查方法

    這篇文章主要介紹了python友情鏈接檢查方法,涉及Python讀取txt文件進行友鏈查詢的相關技巧,非常簡單實用,需要的朋友可以參考下
    2015-07-07
  • Python實現(xiàn)的HMacMD5加密算法示例

    Python實現(xiàn)的HMacMD5加密算法示例

    這篇文章主要介紹了Python實現(xiàn)的HMacMD5加密算法,簡單說明了HMAC-MD5加密算法的概念、原理并結合實例形式分析了Python實現(xiàn)HMAC-MD5加密算法的相關操作技巧,,末尾還附帶了Java實現(xiàn)HMAC-MD5加密算法的示例,需要的朋友可以參考下
    2018-04-04
  • Python&Matlab實現(xiàn)灰狼優(yōu)化算法的示例代碼

    Python&Matlab實現(xiàn)灰狼優(yōu)化算法的示例代碼

    灰狼優(yōu)化算法是一種群智能優(yōu)化算法,它的獨特之處在于一小部分擁有絕對話語權的灰狼帶領一群灰狼向獵物前進。本文具體介紹了灰狼優(yōu)化算法的兩種實現(xiàn)示例代碼,需要的可以參考一下
    2022-03-03
  • python庫TextDistance量化文本之間的相似度算法探究

    python庫TextDistance量化文本之間的相似度算法探究

    這篇文章主要為大家介紹了python庫TextDistance量化文本之間的相似度算法探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01
  • Python偏函數(shù)實現(xiàn)原理及應用

    Python偏函數(shù)實現(xiàn)原理及應用

    這篇文章主要介紹了Python偏函數(shù)實現(xiàn)原理及應用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-11-11
  • 淺談Python用QQ郵箱發(fā)送郵件時授權碼的問題

    淺談Python用QQ郵箱發(fā)送郵件時授權碼的問題

    下面小編就為大家分享一篇淺談Python用QQ郵箱發(fā)送郵件時授權碼的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • Python爬蟲請求模塊Urllib及Requests庫安裝使用教程

    Python爬蟲請求模塊Urllib及Requests庫安裝使用教程

    requests和urllib都是Python中常用的HTTP請求庫,使用時需要根據(jù)實際情況選擇,如果要求使用簡單、功能完善、性能高的HTTP請求庫,可以選擇requests,如果需要兼容性更好、功能更加靈活的HTTP請求庫,可以選擇urllib
    2023-11-11

最新評論