Python教程(27)——如何使用Python中的上下文管理器

来源:https://www.cnblogs.com/kiwiblog/p/18019914
-Advertisement-
Play Games

當我們在編寫代碼時,經常會遇到需要管理資源的情況,比如打開和關閉文件,如果遇到了一些異常情況,我們需要關閉資源,不然會導致資源泄露,雖然我們可以通過手動的方式來關閉,但如果有多個異常情況需要考慮的話,萬一不小心漏了一處,就芭比Q了。所以,如果有一種更加優雅的方式來處理資源泄露的問題,那必定是非常ni ...


當我們在編寫代碼時,經常會遇到需要管理資源的情況,比如打開和關閉文件,如果遇到了一些異常情況,我們需要關閉資源,不然會導致資源泄露,雖然我們可以通過手動的方式來關閉,但如果有多個異常情況需要考慮的話,萬一不小心漏了一處,就芭比Q了。所以,如果有一種更加優雅的方式來處理資源泄露的問題,那必定是非常nice的。而上下文管理器就是在這樣的背景下誕生的。

上下文管理器

上下文管理器(Context Manager)是 Python 中用來管理資源、執行特定操作以及處理異常的對象。上下文管理器通過實現特定的方法使得它們可以在 with 語句中被使用,確保資源的正確獲取和釋放。

在 Python 中,上下文管理器通常使用類中的特殊方法 __enter__ 和 __exit__ 來實現。具體來說:

1、 __enter__ 方法在進入 with 語句塊時被調用,通常用於獲取資源或者執行一些初始化操作,一般返回管理器對象。

2、 __exit__ 方法在離開 with 語句塊時被調用,無論代碼塊中是否發生異常,該方法都會被執行。這個方法通常用來釋放資源,清理工作以及處理異常情況。放法中含有三個參數分別是:異常類型、異常實例對象和異常棧對象

class MyContextManager:
    def __enter__(self):
        print("Entering the context")
        # 執行一些初始化操作,比如打開資源
        return self
        
    def __exit__(self, exc_type, exc_value, traceback):
        print("Exiting the context")
        # 執行一些清理操作,比如關閉資源
        if exc_type is not None:
            print(f"Exception: {exc_type}, {exc_value}")
        # 返回 True 表示異常已經被處理,返回 False 則異常會被傳播
        return True

# 使用上下文管理器
with MyContextManager() as manager:
    print("Inside the context")
    # 執行一些操作,比如讀寫資源
    # 如果在這裡發生了異常,異常會被傳遞給 __exit__ 方法進行處理

比如上面的這個示例中,MyContextManager 是一個簡單的上下文管理器類,通過實現 __enter__ 和 __exit__ 方法來定義上下文管理器的行為。在 with 語句塊中使用該上下文管理器,會執行相應的操作(進入、執行、退出上下文),確保資源的正確管理。

上面的代碼運行結果:

Entering the context
Inside the context
Exiting the context

with語句

很多人說with語句是用來創建上下文管理器,準確的說,這樣子的說法是不對的。之前的例子中,MyContextManager是一個上下文管理器的類,而我們所謂的創建上下文管理器,無非就是創建上下文管理器的對象。那麼以下這樣子不就是創建了一個上下文管理器對象嗎?

m = MyContextManager()

所以準確的說,with語句是Python提供的一種管理上下文的語法結構,能夠自動調用上下文管理器的__enter__和__exit__方法。通過with語句,可以確保在進入和退出代碼塊時自動執行必要的操作。

例如,使用with語句的上下文管理器來打開和關閉文件:

with open('example.txt', 'r') as file:
    content = file.read()
    print(content)

# 文件在with語句塊結束後會自動關閉,即使發生異常也會正確關閉文件

open函數返回的文件對象是一個上下文管理器,本身就不需要再去實現了,通過使用with關鍵字,確保在代碼塊執行完畢後文件會被正確關閉。無需手動調用 file.close() 方法。這樣可以提高代碼可讀性和可維護性,避免忘記關閉文件而導致資源泄漏的問題。

當然我們也可以自己手動實現一個file上下文管理器

class FileContextManager:
    def __init__(self, file_name, mode):
        self.file_name = file_name
        self.mode = mode

    def __enter__(self):
        self.file = open(self.file_name, self.mode)
        return self.file

    def __exit__(self, exc_type, exc_value, exc_traceback):
        if self.file:
            self.file.close()

# 使用自定義的文件上下文管理器類來打開文件
with FileContextManager('example.txt', 'w') as file:
    file.write("程式員一點來啦!")

這個就是一個比較簡單的文件上下文管理器,FileContextManager('example.txt', 'w')和上面open('example.txt', 'r')功能是差不多的。

以上就是關於上下文管理器的一些簡單介紹。總的來說,上下文管理器是 Python 提供的一種非常方便的資源管理機制,可以幫助我們更好地管理和釋放資源,簡化代碼邏輯,提高代碼的健壯性,寫出更加優雅的代碼,在項目開發中使用起來非常的舒服。

更多精彩內容,請關註同名公眾:一點sir(alittle-sir)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Python 常見內置數據類型 在Python中,常用的類型是這些: Python 中查看數據類型的函數(function)為type()。 >>>text = "Is test a string type object?" >>>print(type(text)) <class 'str'> Py ...
  • ServerCnxnFactory 用於接收客戶端連接、管理客戶端session、處理客戶端請求。 ServerCnxn抽象類 代表一個客戶端連接對象: 從網路讀寫數據 數據編解碼 將請求轉發給上層組件或者從上層組件接收響應 管理連接狀態,比如:enableRecv、sessionTimeout、s ...
  • 本文深入介紹了Java 8的Stream API,包括創建、中間操作、終端操作等,強調了並行流在大數據處理中的性能提升。提供清晰實用的示例,為讀者理解流式計算提供有益指導。 ...
  • 在之前的文章中,我們簡單的介紹了線程誕生的意義和基本概念,採用多線程的編程方式,能充分利用 CPU 資源,顯著的提升程式的執行效率。其中java.lang.Thread是 Java 實現多線程編程最核心的類,學習Thread類中的方法,是學習多線程的第一步。 ...
  • 今天我們主要講解的是Spring依賴註入。在本文中,我們主要圍繞bean填充屬性的欄位和setter方法展開討論。要記住的是,在進行屬性註入時,我們首先需要找到註入點併進行緩存,然後才會真正進行屬性註入。需要註意的是,靜態欄位或方法是不會進行依賴註入的。最後,我們簡單地介紹了一下關鍵源碼,以及對@R... ...
  • 通過`FromStr`及`Display`的重定義,我們可以支持更強大的自定義的序列化操作,系統綁定埠既認埠號也認綁定IP,所以我們可以對同個埠進行多次綁定。 ...
  • python打包和反編譯 從py到exe 打包 安裝Pyinstaller pip install pyinstaller //太慢可切源 pip install -i https://pypi.douban.com/simple/ pyinstaller #豆瓣源 pip install -i h ...
  • API介面是一種讓不同系統之間實現數據交互的工具,它可以實現不同系統之間的數據共用和數據傳遞。全國今日油價API介面是一項非常有用的介面,它可以提供最新的全國各省汽油和柴油價格信息。本文將為大家介紹全國今日油價API介面的使用方法,並提供相應代碼說明。 介面名稱:全國今日油價API介面介面地址:ht ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...