《流畅的Python》9-上下文管理器,with 和 else

else 的用法

除了 if/else 外,forwhile 语句都可以使用 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/finallywith内抛出异常会直接跳出。

上下文管理器协议

协议实现了两个接口

  • __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结合在了一起。

你可能感兴趣的:(※,Python,※,读书笔记,《流畅的Python》笔记)