Python实现上下文管理器的方法

 更新时间:2020年08月07日 11:17:14   作者:David Beazley  
这篇文章主要介绍了Python实现上下文管理器的方法,帮助大家更好的理解和学习Python,感兴趣的朋友可以了解下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

问题

你想自己去实现一个新的上下文管理器,以便使用with语句。

解决方案

实现一个新的上下文管理器的最简单的方法就是使用 contexlib 模块中的 @contextmanager 装饰器。 下面是一个实现了代码块计时功能的上下文管理器例子:

import time
from contextlib import contextmanager

@contextmanager
def timethis(label):
  start = time.time()
  try:
    yield
  finally:
    end = time.time()
    print('{}: {}'.format(label, end - start))

# Example use
with timethis('counting'):
  n = 10000000
  while n > 0:
    n -= 1

在函数 timethis() 中,yield 之前的代码会在上下文管理器中作为 __enter__() 方法执行, 所有在 yield 之后的代码会作为 __exit__() 方法执行。 如果出现了异常,异常会在yield语句那里抛出。

下面是一个更加高级一点的上下文管理器,实现了列表对象上的某种事务:

@contextmanager
def list_transaction(orig_list):
  working = list(orig_list)
  yield working
  orig_list[:] = working

这段代码的作用是任何对列表的修改只有当所有代码运行完成并且不出现异常的情况下才会生效。 下面我们来演示一下:

>>> items = [1, 2, 3]
>>> with list_transaction(items) as working:
...   working.append(4)
...   working.append(5)
...
>>> items
[1, 2, 3, 4, 5]
>>> with list_transaction(items) as working:
...   working.append(6)
...   working.append(7)
...   raise RuntimeError('oops')
...
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: oops
>>> items
[1, 2, 3, 4, 5]
>>>

讨论

通常情况下,如果要写一个上下文管理器,你需要定义一个类,里面包含一个 __enter__() 和一个 __exit__() 方法,如下所示:

import time

class timethis:
  def __init__(self, label):
    self.label = label

  def __enter__(self):
    self.start = time.time()

  def __exit__(self, exc_ty, exc_val, exc_tb):
    end = time.time()
    print('{}: {}'.format(self.label, end - self.start))

尽管这个也不难写,但是相比较写一个简单的使用 @contextmanager 注解的函数而言还是稍显乏味。

@contextmanager 应该仅仅用来写自包含的上下文管理函数。 如果你有一些对象(比如一个文件、网络连接或锁),需要支持 with 语句,那么你就需要单独实现 __enter__() 方法和 __exit__() 方法。

以上就是Python实现上下文管理器的方法的详细内容,更多关于Python实现上下文管理器的资料请关注程序员之家其它相关文章!

相关文章

  • 如何在python中使用selenium的示例

    如何在python中使用selenium的示例

    这篇文章主要介绍了如何在python中使用selenium的示例,selenium提供了一个通用的接口,可模拟用户来操作浏览器,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • python回归分析逻辑斯蒂模型之多分类任务详解

    python回归分析逻辑斯蒂模型之多分类任务详解

    这篇文章主要为大家介绍了python回归分析逻辑斯蒂模型之多分类任务详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • python SVD压缩图像的实现代码

    python SVD压缩图像的实现代码

    这篇文章主要介绍了python SVD压缩图像的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • python爬取数据中的headers和代理IP问题分析

    python爬取数据中的headers和代理IP问题分析

    这篇文章主要为大家介绍了python爬取数据中的headers和代理IP问题分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • python将文本中的空格替换为换行的方法

    python将文本中的空格替换为换行的方法

    这篇文章主要介绍了python将文本中的空格替换为换行的方法,需要的朋友可以参考下
    2018-03-03
  • 基于Python实现一个自动关机程序并打包成exe文件

    基于Python实现一个自动关机程序并打包成exe文件

    这篇文章主要介绍了通过Python创建一个可以自动关机的小程序,并打包成exe文件。文中的示例代码讲解详细,对我们学习Python有一定的帮助,感兴趣的同学可以了解一下
    2021-12-12
  • Python使用shelve模块实现简单数据存储的方法

    Python使用shelve模块实现简单数据存储的方法

    这篇文章主要介绍了Python使用shelve模块实现简单数据存储的方法,涉及shelve模块实现数据存储的技巧,需要的朋友可以参考下
    2015-05-05
  • 正确理解python迭代器与生成器

    正确理解python迭代器与生成器

    在Python这门语言中,生成器毫无疑问是最有用的特性之一。与此同时,也是使用的最不广泛的Python特性之一。究其原因,主要是因为,在其他主流语言里面没有生成器的概念。本文将详细介绍python迭代器与生成器
    2021-06-06
  • python新手学习可变和不可变对象

    python新手学习可变和不可变对象

    在本篇文章里小编给大家分享了是一篇关于python可变对象和不可变对象的基础知识点内容,有需要的朋友们可以参考下。
    2020-06-06
  • Python 如何求矩阵的逆

    Python 如何求矩阵的逆

    这篇文章主要介绍了Python 如何求矩阵的逆案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03

最新评论

?


http://www.vxiaotou.com