python的上下文管理器

Python中的上下文

上下文管理器是python中的一种协议,实现了这种协议的类的实例,都是上下文管理器对象。

文件的输入输出,数据库的链接断开,都是很常见的资源管理操作。但是资源都是有限的,在编写程序的时候。我们必须保证这些资源在使用完之后得到释放,不然就很容易造成资源泄露。上下文管理器,能够实现自动分配并且释放资源。

在python中实现上下文协议并创建上下文管理器对象的方法有两种,一种是基于类的上下文管理器,一种是基于生成器的上下文管理器。

1 基于类的上下文管理器

用类实现上下文管理器,在定义类的时候,实现两个方法“enter()”和“exit()”。enter返回需要被管理的资源;exit里通常会存在一些释放、清理资源的操作。比如这个例子中关闭文件等等

class FileManager(object):
    def __init__(self, name, mode):
        print("calling __init__ method")
        self.name = name
        self.mode = mode
        self.file = None

    def __enter__(self):
        print("calling __enter__ method")
        self.file = open(self.name, self.mode)
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("calling __exit__ method")
        if self.file:
            self.file.close()


with FileManager("test.txt", "w") as f:
    print("write to the file")
    f.write("hello world")
    
###########################output####################################
"""
calling __init__ method
calling __enter__ method
write to the file
calling __exit__ method
"""

方法exit()中的参数 exc_type, exc_val, exc_tb 分别表示exception_type, exception_value, traceback。当我们执行包含有上下文管理器的with语句时, 如果有异常抛出,异常的信息就会包含在这三个变量中,传入方法exit()。

class FileManager(object):
    def __init__(self, name, mode):
        print("calling __init__ method")
        self.name = name
        self.mode = mode
        self.file = None

    def __enter__(self):
        print("calling __enter__ method")
        self.file = open(self.name, self.mode)
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("""calling __exit__ method: 
                exc_type: %s;
                exc_val: %s;
                exc_tb: %s
        """ % (exc_type, exc_val, exc_tb))
        if self.file:
            self.file.close()


with FileManager("test.txt", "w") as f:
    print("write to the file")
    raise ValueError(123)
    f.write("hello world")
    
#################################output#######################################
"""
calling __init__ method
calling __enter__ method
write to the file
calling __exit__ method: 
                exc_type: <class 'ValueError'>;
                exc_val: 123;
                exc_tb: <traceback object at 0x000001A74C7B2BC8>

"""

2 基于生成器的上下文管理器

使用装饰器 contextlib.contextmanager 来定义自己所需的基于生成器的上下文管理器,用以支持with语句

# coding: utf-8
"""
基于生成器的上下文管理器
"""
import contextlib
from contextlib import contextmanager

@contextmanager
def file_manager(name, mode):
    try:
        f = open(name, mode)
        yield f
    finally:
        f.close()


with file_manager("test.txt", "w") as t:
    t.write("welcome")

代码中,函数file_manager()是一个生成器,当我们执行with语句的时候,便会打开文件,并返回文件对象f; 当 with 语句执行完后,finally 中的关闭文件操作便会执行。

3 比较

  1. 基于类的上下文管理器更加灵活,适用于大型的系统开发
  2. 基于生成器的上下文管理器更加方便,简洁,适用于中小程序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值