美文网首页
Fluent Python笔记--上下文管理器

Fluent Python笔记--上下文管理器

作者: MontyOak | 来源:发表于2018-04-25 20:06 被阅读12次

所谓上下文管理器,就是Python中常见的with...as...语法。它实质上包含__enter__方法和__exit__方法(可以参考我的这篇文章)。
其中__enter__方法的入参只有实例绑定self。而__exit__方法的入参则除了self还有exc_type(异常类),exc_value(异常实例),traceback(traceback对象)。
下面简单实现一个上下文管理器:

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


>>> from mirror import LookingGlass
>>> manager = LookingGlass() 
>>> manager
<mirror.LookingGlass object at 0x2a578ac>
>>> monster = manager.__enter__() 
>>> monster == 'JABBERWOCKY' 
eurT
>>> monster
'YKCOWREBBAJ'
>>> manager
>ca875a2x0 ta tcejbo ssalGgnikooL.rorrim<
>>> manager.__exit__(None, None, None) 
>>> monster
'JABBERWOCKY 

在标准库中,可以经常看见对于上下文管理器的使用:

  • sqlite3中用于管理事务
  • threading中用于维护锁、信号和条件

除了实现__enter____exit__之外,也可以使用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 


>>> from mirror_gen import looking_glass
>>> with looking_glass() as what: 
... print('Alice, Kitty and Snowdrop')
... print(what)
...
pordwonS dna yttiK ,ecilA
YKCOWREBBAJ
>>> what
'JABBERWOCKY'

contextlib.contextmanager 装饰器会把函数包装成实现__enter____exit__ 方法的类。
其中__enter__方法有如下作用:
(1) 调用生成器函数,保存生成器对象(这里把它称为 gen )。
(2) 调用 next(gen) ,执行到 yield 关键字所在的位置。
(3) 返回 next(gen) 产出的值,以便把产出的值绑定到 with/as 语句中的目标变量上。
__exit__方法则有以下作用:
(1) 检查有没有把异常传给 exc_type ;如果有,调用gen.throw(exception) ,在生成器函数定义体中包含 yield 关键字的那一行抛出异常。
(2) 否则,调用 next(gen) ,继续执行生成器函数定义体中 yield 语句之后的代码。

相关文章

  • Fluent Python笔记--上下文管理器

    所谓上下文管理器,就是Python中常见的with...as...语法。它实质上包含__enter__方法和__e...

  • 算法面试 - 问题记录

    python上下文管理器,装饰器? (1)上下文管理器知乎链接:https://zhuanlan.zhihu.co...

  • Python上下文管理器和with块

    python中with语句用起来很方便,那这后边的原理就是python中的上下文管理器。 1.什么是上下文管理器 ...

  • python 上下文管理器

    一、什么是上下文管理器? 上下文管理器类型是python的内置类型之一,上下文管理器的定义:允许用户自定义类来定义...

  • python上下文管理

    什么是上下文管理 上下文:context的直译, 指的是代码执行过程中的前后状态上下文管理器:python上下文管...

  • Python上下文管理器

    Context Manager 文档翻译 Python with语句支持上下文管理器定义的运行时上下文概念(run...

  • Tornado源码分析(二)异步上下文管理(StackConte

    异步异常与上下文 在Python黑魔法---上下文管理器最后关于上下文的使用,提到了tornado的处理方式。本篇...

  • python 基础深入

    contextlib 上下文管理器 创建上下文管理实际就是创建一个类,添加enter和exit方法 Python...

  • Python Metaprogramming

    Fluent Python Metaprogramming 部分的笔记, 在加上了其他杂七杂八的东西 Dynami...

  • Python上下文管理器

    上下文管理器 概念:实现了上下文协议的对象即为上下文管理器。 上下文管理器的协议: __enter__进入的方法_...

网友评论

      本文标题:Fluent Python笔记--上下文管理器

      本文链接:https://www.haomeiwen.com/subject/cygylftx.html