上下文管理器和else块
if 语句之外的else块
- for···else···
for运行完毕时才运行else块
my_list = ['apple']
for item in my_list:
if item == 'banana':
break
else:
raise ValueError('No banana flavor found!')
-
while···else···:仅当while循环因为条件为假值而退出时才运行else块
-
try···except··else···:仅当try块中没有异常抛出时才运行else块
try:
dangerous_call()
except OSError:
log('OSError')
else:
after_call() # 没有抛出异常才运行
上下文管理器与with
上下文管理器对象存在的目的是管理with语句
上下文管理器协议包含__enter__和__exit__方法,with语句开始运行时,调用__enter__方法,with运行结束时调用__exit__方法
- 确保关闭文件对象
with open('debug.log') as fp:
src = fp.read(60)
len(src)
fp
fp.closed, fp.encoding
fp.read(60) # 文件对象已经关闭,不能在fp上执行I/O操作
- 上下文管理器
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
测试
with LookingGlass() as what:
print('Alice, Kitty and Snowdrop') # 在上下文管理器中调用__enter__方法,将字符串倒置
print(what)
# 上下文管理器关闭LookingGlass后调用__exit__方法,将倒置字符还原
print(what)
print('Back to normal.')
使用生成器实现的上下文管理器
import contextlib
@contextlib.contextmanager
def looking_glass():
import sys
original_write = sys.stdout.write # 保留原理的输出
def reverse_write():
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)
总结
- 补充了else块在for、while和try中的使用
- 上下文管理器的使用和实现的__enter__和__exit__方法
- 使用生成器优化上下文管理器
流程的Python