Python上下文管理器全例項詳解
阿新 • • 發佈:2020-01-09
Python上下文管理器
簡介
最近用到這個,仔細瞭解了一下,感覺是十分有用的,記錄一下
使用場景
當我們需要獲取一個臨時開啟的資源,並在使用完畢後進行資源釋放和異常處理,利用try-catch語句可以完成,舉個例子。
開啟檔案:
f = None try: print("try") f = open("__init__.py","r") print(f.read()) except Exception as e: print("exception") finally: if f: print("finally") f.close()
利用上下文管理器:
class OpenHandle: def __init__(self,filename,mode): self.filename = filename self.mode = mode def __enter__(self): self.f = open(self.filename,self.mode) return self.f def __exit__(self,exc_type,exc_val,exc_tb): if exc_type: print("exception") else: print("normal") self.f.close() with OpenHandle("book.txt","r") as f: print(f.read())
這樣可以利用with-as語句改寫程式碼,讓程式設計師關注業務主流程,去掉對於資源的獲取和關閉這些重複操作。提升程式碼的可讀性。好處很大。
執行順序
執行順序是理解這種寫法的關鍵:
- 初始化,執行handle的__init__()
- __enter__()方法,獲取資源物件,返回給as後的變數
- 業務程式碼邏輯
- __exit__方法,傳入3個引數,異常型別,異常物件,呼叫棧物件,無異常都為None
- 丟擲異常或者正常結束
函式式上下文管理器
利用from contextlib import contextmanager這個裝飾器可以將函式裝飾為上下文管理器,其實這個裝飾背後也是返回一個實現了__enter__和__exit__方法的類
from contextlib import contextmanager @contextmanager def managed_resource(*args,**kwds): # Code to acquire resource,e.g.: resource = acquire_resource(*args,**kwds) try: yield resource finally: # Code to release resource,e.g.: release_resource(resource) >>> with managed_resource(timeout=3600) as resource: ... # Resource is released at the end of this block,... # even if code in the block raises an exception
模板程式碼
sqlalchemy會話上下文管理器
利用這個管理sqlalchemy會話物件的獲取和釋放,控制事務是再合適不過了
class DbTransaction: def __init__(self,session_maker): self.session_maker = session_maker def __enter__(self): self.session = self.session_maker() return self.session def __exit__(self,exc_tb): if exc_type: self.session.rollback() else: self.session.commit() self.session.close() return False if exc_type else True
以上就是全部相關知識點,感謝大家的學習和對我們的支援。