Python 上下文管理器 with 相关用法

Python 上下文管理器

什么是上下文管理器?
  • context manager
  • 一个上下文管理器是一个对象
  • 它定义了运行时的上下文
  • 使用 with 语句来执行
with 语句
with context as ctx:
		#  使用这个上下文对象
#  上下文对象已经被清除

​ 这里我们使用 Python的文件操作 打开一个文件并写入一段话

instance = open('data.txt', 'w')  # 打开文件
instance.write('What a wonderful house')
instance.close()  # 关闭文件

​ 对于上面的代码,我们可以用 with 语句进行代替,并且只需要两行。

with open('data.txt', 'w') as instance:
    instance.write('What a wonderful house')

​ 这是因为在 with 语句结束时,会自动调用文件的关闭 close 函数,避免出现异常。

上下文管理器的协议

一个上下文管理器需要实现如下方法:

  • __enter__() 安装上下文,可以返回对象
  • __exit__() 清楚释放对象

​ 这里我们举个计算一段程序用时时长的例子,time.perf_counter是用于测量代码执行时间的功能。它返回一个高分辨率的性能计数器,通常用于测量短时间内的代码执行时间。

import time


start = time.perf_counter()
list1 = []
for i in range(1, 10000):
    list1.append(i ** 2)

end = time.perf_counter()
elapsed = end - start
print(elapsed)

​ 为了实现对于任意代码段都可以调用这个计算时长的例子,我们定义 Timer 类来实现整个程序流程,__enter__作为进入方法,__exit()__作为退出方法。

class Timer:
    def __init__(self):
        self.elapsed = 0

    def __enter__(self):
        self.start = time.perf_counter()
        return self  #  必须实现

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end = time.perf_counter()
        self.elapsed = self.end - self.start
        return False  # 如果在with范围内出现了异常,在exit的时候可以告诉Python是否继续向外抛出,如果return True,那么就表示不抛出了,return False表示继续抛出。当然如果没有异常,这里return什么就无所谓了

​ 主体调用代码部分。

with Timer() as t:
    list1 = []
    for i in range(1, 10000):
        list1.append(i ** 2)

    end = time.perf_counter()
print(t.elapsed)

​ 下面我们来解释一下代码的执行流程:

  1. Time()创建对象,调用我们定义的 __init__初始化方法,实现了变量的初始化
  2. with 语句会调用 __enter__方法,执行 __enter__方法主体内容,并且将返回值传给 as 后面定义的变量,这里是 t。(所以 t 并不是对 Timer()的引用,而是 Timer().__enter__的返回值。
  3. 当代码段调用结束时,程序会调用 __exit__ 方法进行退出,生成我们需要的整体代码运行时间变量 elapsed。

也就是说,我们之前使用 with 语句打开文件实现文件的退出,本质上是 open 打开的内置的 __exit__ 函数帮我们实现了这样一个功能。

上下文管理的应用

上下文管理器一般的应用场景:

  • 开 - 关
  • 锁 - 释放
  • 启动 - 停止
  • 改变 - 重置
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值