標籤:參數傳遞 管理方法 final 運行環境 finally 魔法 contex str 錯誤
關於計算機啟動並執行內容相關的概念,我的理解也不是很深;按我的理解就是程式在運行之前,其所需要的資源,運行環境等都會被序列化,然後加入到CPU的任務隊列中,等待調度系統分配時間片執行。下面談談python上下文管理器的使用。
自訂上下文管理器
- python中最常用的上下文管理器就是檔案的開啟和關閉了。
with open(filename,‘r‘) as file: file.read()
原理
- python上下文使用with觸發,內部實現了__enter__和__exit__兩個魔法方法。
class context(object): def __init__(self): print(‘aaaa‘) def __enter__(self): print(‘bbbb‘) def __exit__(self, exc_type, exc_val, exc_tb): print(‘cccc‘)# exc_type:異常的類型;# exc_val:異常的詳細資料;# exc_tb:異常發生的位置;# 如果沒有發生異常,以上三個值都是Nonewith context() as f: ‘‘‘主體邏輯‘‘‘ print(‘xxxx‘)# 輸出aaaabbbbxxxxcccc
- 當使用with觸發管理器的時候,先初始化執行__init__得到一個對象,然後執行__enter__方法,再執行主體程式的邏輯,最後執行__exit__方法。
注意
當程式主體邏輯執行完畢退出with語句塊或者主體邏輯代碼塊出現異常,則會自動執行__exit__方法,並且會把對於的異常參數傳遞進來;如果沒有異常,傳遞的是None。
如果主體邏輯代碼發生了錯誤,但是__exit__函數返回True,則with語句主體邏輯代碼塊異常不會被拋出,終止程式;如果返回None或者False,異常會被主動raise,並終止程式。
總結上下文管理器的完整的原理
初始化擷取一個上下文管理器對象;
載入上下文管理器的 exit() 方法備用;
調用上下文管理器的 enter() 方法;如果有 as f從句,則將 enter() 方法的傳回值賦給f;
執行主體邏輯代碼塊;
調用上下文管理器的 exit() 方法;
python的上下文管理工具contextlib
import contextlib@contextlib.contextmanagerdef test(): print(‘aaaaaa‘) try: yield 1 finally: print(‘bbbbb‘)with test() as f: print(‘ccccc‘)# 輸出aaaaaacccccbbbbb
底層簡化版的原理
class ContextTest(object): def __init__(self): self.f = self.test() def __enter__(self): return next(self.f) def __exit__(self, exc_type, exc_val, exc_tb): try: next(self.f) except StopIteration: return False def test(self): print(‘aaaaaa‘) try: yield 1 finally: print(‘bbbbb‘)with ContextTest() as f: print(f) print(‘kkkkkk‘)
先初始化一個ContextTest上下文管理器對象對象,得到一個對象的產生器test()
載入上下文管理器的 exit() 方法備用;
調用上下文管理器的 enter() 方法;執行next()方法喚醒test()產生器,執行yield關鍵字前面的代碼;
執行主體邏輯代碼;
調用上下文管理器的 exit() 方法;該方法調用next()方法再次喚醒產生器,執行yield關鍵字後面的代碼;
python之上下文管理器