美文网首页
python中的上下文管理器和with

python中的上下文管理器和with

作者: 伍只蚊 | 来源:发表于2017-07-19 18:05 被阅读35次

之前只知道with...as语句可以作用于一些资源文件的操作,比如filelike对象,可以使它打开后,即使异常也自动关闭,还有线程锁的获取与释放。
其实with的作用对象不止这些,只要是上下文管理器对象,都能应用with语句

什么是上下文管理器?

我们用with打开一个文件对象,with语句其实实现了 打开文件,执行代码块,关闭文件的流程。上下文管理器其实就是 在执行代码块 之前做一些准备,做完之后在做一些善后的工作,这就完成了对代码块中的这一部分的上下文的管理。

怎么实现上下文管理器?

  1. 自定义类实现两个魔法方法:enter,exit
class Son(object):
    def __init__(self,name):
        self.name = name

    def __enter__(self):
        print('%s诞生了'%self.name)
    def __exit__(self, exc_type, exc_val, exc_tb):
        
            print('顺利诞生')


s = Son('wu')
with s as g:
    print(s.name)
    
    
    结果:
    wu诞生了
    wu
    顺利诞生
    

enter方法中执行的工作就是进入代码块前干的准备工作,他的返回值可以用as接收,而exit中干的就是代码块执行完后的工作。
若在执行代码块中发生异常,exit方法仍会执行,并且可以捕获到异常信息,具体详情我还没搞明白。

2.通过@contextmanager将一个生成器变为上下文管理器
@contextmanager是contextlib模块下的一个装饰器,他接收的函数必须是生成器

import contextlib


@contextlib.contextmanager
def get_file(filename):
    print('正在打开文件')
    f = open(filename,'r',encoding='utf8')  #代码块执行前的准备工作
    yield f
    print('正在关闭文件')
    f.close()#执行后的善后工作

with get_file('test.py') as g:
    print('正在读取文件')
    print(g.read())

结果:
正在打开文件
正在读取文件
#coding=utf8
文件内容
正在关闭文件

在被装饰的生成器函数中,yield之前的部分就是 代码块执行前准备的内容,yield之后的就是代码块执行后的善后处理,yield返回的值可以用 as 赋予一个变量,在代码块中使用。
通过contextmanager装饰的生成器返回的是上下文管理器,这样就可以用with语句了。

3.通过context.closing类把一个对象变为上下文管理器对象

import contextlib
from urllib.request import urlopen

with contextlib.closing(urlopen('http://wwww.baidu.com')) as f:
    print(f.readline())

这是closing类的源码,其实就是传入对象初始化一个上下文管理器类对像,在exit中实现调用close(),在enter中返回原来的对象,用as可以获取

class closing(AbstractContextManager):
  
    def __init__(self, thing):
        self.thing = thing
    def __enter__(self):
        return self.thing
    def __exit__(self, *exc_info):
        self.thing.close()

总结一下:上下文管理器总是配合with语句一起使用,作用是在with语句块的执行前和执行后完成指定功能。
创建上下文管理器的方法有三种:

  1. 自定义类,实现enter,和exit方法
  2. 通过 @contextmanager将一个生成器变为上下文管理器,yield前后分别在代码块前后执行
  3. 利用context.closing类把一个对象变为上下文管理器对象,传入对象参数,在exit中调用对象的close方法

相关文章

  • Python上下文管理器和with块

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

  • python上下文管理

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

  • 算法面试 - 问题记录

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

  • python 上下文管理器

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

  • python 基础深入

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

  • python中上下文管理器

    什么是上下文管理器? 代码的环境就是上下文,实现了上下文管理器协议的类产生的实例就是上下文管理器对象。在类中声名e...

  • 关于async with 表达式

    与 with 中的上下文管理器需要定义两个方法 enter() 和 exit() 一样,异步上下文管理器同样也需要...

  • Python上下文管理器

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

  • python中的上下文管理器和with

    之前只知道with...as语句可以作用于一些资源文件的操作,比如filelike对象,可以使它打开后,即使异常也...

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

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

网友评论

      本文标题:python中的上下文管理器和with

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