with语句开始运行时,会在上下文管理器对象上调用 __enter__ 方法,with 语句运行结束后,会在上下文管理器对象上调用__exit__方法。不管控制流程以哪种方式退出 with块,都会在上下文管理器对象上调用__exit__方法。
我们先定义一个上下文管理器用到的类,
class LookingGlass:
def __enter__(self): ①
import sys
self.original_write = sys.stdout.write
sys.stdout.write = self.reverse_write ②
return 'enter return value'
def reverse_write(self, text): ③
self.original_write(text[::-1])
def __exit__(self, exc_type, exc_value, traceback):
import sys
sys.stdout.write = self.original_write ④
if exc_type is ZeroDivisionError:
print('Please DO NOT divide by zero!')
return True
①除了 self 之外,Python 调用 __enter__ 方法时不传入其他参数,②使用自定义的self.reverse_write取代标准输出函数,③定义自定义输出函数,④还原成原来的标准输出函数
>>> from LookingGlass import LookingGlass
>>> with LookingGlass() as what:
... print("python code") ⑤
... print(what) ⑥
...
edoc nohtyp
eulav nruter retne ⑦
>>> print('python code')
python code ⑧
⑤⑥在LookingGlass的上下文管理器对象中,打印是相反的值,⑦打印what,即__enter__⑧退出上下文管理器后打印正常顺序的值。
不用with直接使用__enter__,__exit__
>>> from LookingGlass import LookingGlass
>>> manager=LookingGlass()
>>> manager.__enter__()
'eulav nruter retne'
>>> print('python code')
edoc nohtyp
>>> manager.__exit__(None,None,None)
>>> print('python code')
python code
Python 上下文管理器和with块一 https://blog.csdn.net/s695811494/article/details/112094191