python基础之上下文管理器

前言

关于计算器运行的上下文的概念,我的理解也不是很深;按我的理解就是程序在运行之前,其所需要的资源,运行环境等都会被序列化,然后加入到CPU的任务队列中,等待调度系统分配时间片执行。下面谈谈python上下文管理器的使用。

系列文章

上下文管理器

  • python中最常用的上下文管理器就是文件的打开和关闭了。
with open(filename,'r') as file:
    file.read()

原理

  • python上下文使用with触发,内部实现了__enter__和__exit__两个魔法方法。
class context(object):
    def __init__(self):
        print('aaaa')

    def __enter__(self):
        print('bbbb')

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('cccc')

# exc_type:异常的类型;
# exc_val:异常的详细信息;
# exc_tb:异常发生的位置;
# 如果没有发生异常,以上三个值都是None

with context() as f:
    '''主体逻辑'''
    print('xxxx')

# 输出
aaaa
bbbb
xxxx
cccc
  • 当使用with触发管理器的时候,先初始化执行__init__得到一个对象,然后执行__enter__方法,再执行主体程序的逻辑,最后执行__exit__方法。

注意

  • 当程序主体逻辑执行完毕退出with语句块或者主体逻辑代码块出现异常,则会自动执行__exit__方法,并且会把对于的异常参数传递进来;如果没有异常,传递的是None。

  • 如果主体逻辑代码发生了错误,但是__exit__函数返回True,则with语句主体逻辑代码块异常不会被抛出,终止程序;如果返回None或者False,异常会被主动raise,并终止程序。

总结上下文管理器的完整的原理

  1. 初始化获取一个上下文管理器对象;

  2. 加载上下文管理器的 exit() 方法备用;

  3. 调用上下文管理器的 enter() 方法;如果有 as f从句,则将 enter() 方法的返回值赋给f;

  4. 执行主体逻辑代码块;

  5. 调用上下文管理器的 exit() 方法;

python的上下文管理工具contextlib

python内置了对于上下文管理器更优雅的管理方法

import contextlib

@contextlib.contextmanager
def test():
    print('aaaaaa')
    try:
        yield 1
    finally:
        print('bbbbb')

with test() as f:
    print('ccccc')

# 输出
aaaaaa
ccccc
bbbbb

底层简化版的原理

class ContextTest(object):
    def __init__(self):
        self.f = self.test()

    def __enter__(self):
        return next(self.f)

    def __exit__(self, exc_type, exc_val, exc_tb):
        try:
            next(self.f)
        except StopIteration:
            return False

    def test(self):
        print('aaaaaa')
        try:
            yield 1
        finally:
            print('bbbbb')

with ContextTest() as f:
    print(f)
    print('kkkkkk')

  • 说明:
  1. 先初始化一个ContextTest上下文管理器对象,得到一个对象的生成器test()

  2. 加载上下文管理器的 exit() 方法备用;

  3. 调用上下文管理器的 enter() 方法;执行next()方法唤醒test()生成器,执行yield关键字前面的代码;

  4. 执行主体逻辑代码;

  5. 调用上下文管理器的 exit() 方法;该方法调用next()方法再次唤醒生成器,执行yield关键字后面的代码;

参考

posted @ 2018-03-19 11:49  倥偬时光  阅读(761)  评论(0编辑  收藏  举报