自定義上下文管理器:需要實(shí)現(xiàn)__enter__
方法和 __exit__
方法
微信截圖_20200227163024.png
class Test:
def __enter__(self):
print("enter")
return "XXX "
# return self
def __exit__(self, exc_type, exc_val, exc_tb):
# exc_type 異常的類(lèi)型匿辩;exc_val 異常的值;exc_tb 異常的追蹤信息
print(self, exc_type, exc_val, exc_tb)
# 提取異常信息
import traceback
print(traceback.extract_tb(exc_tb))
print("exit")
# 返回值為T(mén)rue端姚,將不在對(duì)外界拋出異常信息;如果為False或者None上枕,將對(duì)外拋出異常信息
return True
with Test() as T:
print("上下文管理器的語(yǔ)句體")
print(T)
1/0
# 運(yùn)行結(jié)果
enter
上下文管理器的語(yǔ)句體
XXX
<__main__.Test object at 0x000001ECFBBD8400> <class 'ZeroDivisionError'> division by zero <traceback object at 0x000001ECFD86FA80>
[<FrameSummary file C:/code/python繼承.py, line 25 in <module>>]
exit
contextlib 模塊
@contextlib.contextmanager丸卷,使用裝飾器, 讓一個(gè)生成器變成一個(gè)"上下文管理器"
import contextlib
@contextlib.contextmanager
def Test():
# yield 語(yǔ)句前面的代碼當(dāng)中 __enter__來(lái)執(zhí)行;yield 語(yǔ)句后面的代碼當(dāng)作 __exit__來(lái)執(zhí)行
print(1)
yield "XXX"
print(2)
with Test() as T:
print(3, T)
#代碼執(zhí)行
1
3 XXX
2
import contextlib
@contextlib.contextmanager
def Test():
try:
yield
except ZeroDivisionError as e:
print("error: ", e)
with Test() as T:
1/0
#運(yùn)行結(jié)果
error: division by zero
contextlib.closing捐名,這個(gè)函數(shù), 讓一個(gè)擁有close方法但不是上下文管理器的對(duì)象變成"上下文管理器"
class Test:
def t(self):
print("t函數(shù)執(zhí)行")
def close(self):
print("釋放資源")
#
# def __enter__(self):
# return self
#
# def __exit__(self, exc_type, exc_val, exc_tb):
# self.close()
import contextlib
with contextlib.closing(Test()) as T:
T.t()
#運(yùn)行結(jié)果
t函數(shù)執(zhí)行
釋放資源