寫代碼時,我們希望把一些操作放到一個代碼塊中,這樣在代碼塊中執行時就可以保持在某種運行狀態,而當離開該代碼塊時就執行另一個操作,結束當前狀態;所以,簡單來說,上下文管理器的目的就是規定對象的使用范圍,如果超出范圍就采取“處理”。
這一功能是在Python2.5之后引進的,它的優勢在于可以使得你的代碼更具可讀性,且不容易出錯。
1 模塊簡介
在數年前,Python 2.5 加入了一個非常特殊的關鍵字,就是with。with語句允許開發者創建上下文管理器。什么是上下文管理器?上下文管理器就是允許你可以自動地開始和結束一些事情。例如,你可能想要打開一個文件,然后寫入一些內容,最后再關閉文件。這或許就是上下文管理器中一個最經典的示例。事實上,當你利用with語句打開一個文件時,Python替你自動創建了一個上下文管理器。
with open("test/test.txt","w") as f_obj: f_obj.write("hello")如果你使用的是Python 2.4,你不得不以一種老的方式來完成這個任務。
f_obj = open("test/test.txt","w")f_obj.write("hello")f_obj.close()上下文管理器背后工作的機制是使用Python的方法:__enter__和__exit__。讓我們嘗試著去創建我們的上下文管理器,以此來了解上下文管理器是如何工作的。
2 模塊使用
2.1 創建一個上下文管理器類
與其繼續使用Python打開文件這個例子,不如我們創建一個上下文管理器,這個上下文管理器將會創建一個SQLite數據庫連接,當任務處理完畢,將會將其關閉。下面就是一個簡單的示例。
import sqlite3class DataConn: def __init__(self,db_name): self.db_name = db_name def __enter__(self): self.conn = sqlite3.connect(self.db_name) return self.conn def __exit__(self,exc_type,exc_val,exc_tb): self.conn.close() if exc_val: raiseif __name__ == "__main__": db = "test/test.db" with DataConn(db) as conn: cursor = conn.cursor()
在上述代碼中,我們創建了一個類,獲取到SQLite數據庫文件的路徑。__enter__方法將會自動執行,并返回數據庫連接對象。現在我們已經獲取到數據庫連接對象,然后我們創建光標,向數據庫寫入數據或者對數據庫進行查詢。當我們退出with語句的時候,它將會調用__exit__方法用于執行和關閉這個連接。
讓我們使用其它的方法來創建上下文管理器。
2.2 利用contextlib創建一個上下文管理器
Python 2.5 不僅僅添加了with語句,它也添加了contextlib模塊。這就允許我們使用contextlib的contextmanager函數作為裝飾器,來創建一個上下文管理器。讓我們嘗試著用它來創建一個上下文管理器,用于打開和關閉文件。
新聞熱點
疑難解答