else 的用法
除了 if/else
外,for
,while
语句都可以使用 else
。
举例
for i in range(10):
if i == 11:
break
else:
print('magic')
含义显而易见,处理for
循环里没有被处理的情况,优点是不用设置特殊标志来判断。
上下文管理器
with
语句处理的对象就是上下文管理器
,关键字 as
可选。实际上 as
通过调用 __enter__
方法,返回了相对应的值,若没有指定甚至可能是 None
。
with 语句
with
语句是为了简化 try/finally
模式,
平时多用于自动关闭打开的文件。
with open('/home/jo/1.py') as py:
#todo
pass
可以理解相当于执行了一段 try/finally
,with
内抛出异常会直接跳出。
上下文管理器协议
协议实现了两个接口
__enter__
__exit__
__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
LookingGlass
类实现倒序输出,注意__exit__
类的三个参数:
exc_type
异常类(例如ZeroDivisionError
)exc_value
异常实例。有时会有参数传给异常构造方法,例如错误消息,这些参数可以使用exc_value.args
获取。traceback
,traceback
对象。
contextlib 模块
contextlib
模块提供了一系列方便自定义上下文管理器的工具。
@contextmanager
这个装饰器把简单的生成器函数变成上下文管理器,这样就不用创
建类去实现管理器协议了。`
用法也非常简单,所谓的生成器函数实现上下文管理器。
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 ➍
yield 'JABBERWOCKY' ➎
sys.stdout.write = original_write ➏
yield
前面部分即为__ent__
,后面部分即为__exit__
。
@contextmanager
把 函数装饰器,生成器和with
结合在了一起。