with open("a.txt") as f:
f.read()
__enter__
和__exit__
两个方法,所以要实现一个上下文管理器,就得实现这两个方法,比如:class LookingGlass:
def __enter__(self):
import sys
self.original_write = sys.stdout.write
sys.stdout.write = self.reverse_write
return 'JABBERWOCKY'
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
__enter__
是上下文管理器的入口,在with语句开始运行时调用。
__exit__
是上下文管理器的出口,在with语句运行结束后调用。
with LookingGlass() as what:
print(what)
__enter__
了。@contextmanager
装饰器能减少创建上下文管理器的样板代码量,只需要实现一个有yield语句的生成器,生成想让__enter__
方法返回的值。import contextlib
@contextlib.contextmanager
def looking_glass():
import sys
original_write = sys.stdout.write
def reverse_write(text):
original_write(text[::-1])
sys.stdout.write = reverse_write
msg = ''
try:
yield 'JABBERWOCKY'
except ZeroDivisionError:
msg = 'Please DO NOT divide by zero!'
finally:
sys.stdout.write = original_write
if msg:
print(msg)
在yield语句前面的代码在with块开始时执行,相当于__enter__
。
在yield语句后面的代码在with块结束时执行,相当于__exit__
。
参考资料: 《流畅的Python》第15章 上下文管理器和else块
联系客服