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

 更新时间:2020年08月07日 11:17:14   作者:David Beazley  
这篇文章主要介绍了Python实现上下文管理器的方法,帮助大家更好的理解和学习Python,感兴趣的朋友可以了解下

问题

你想自己去实现一个新的上下文管理器,以便使用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正则表达式的应用详解

    Python正则表达式的应用详解

    这篇文章主要介绍了Python中正则表达式的详细教程,正则表达式是Python学习进阶当中的重要内容,需要的朋友可以参考下,希望能给你带来帮助
    2021-08-08
  • 使用tensorflow根据输入更改tensor shape

    使用tensorflow根据输入更改tensor shape

    这篇文章主要介绍了使用tensorflow根据输入更改tensor shape,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-06-06
  • Python如何优雅获取本机IP方法

    Python如何优雅获取本机IP方法

    这篇文章主要介绍了Python如何优雅获取本机IP方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • python函数map()和partial()的知识点总结

    python函数map()和partial()的知识点总结

    在本篇文章里小编给大家分享了关于python函数map()和partial()的知识点总结,需要的朋友们可以参考下。
    2020-05-05
  • python中使用sys模板和logging模块获取行号和函数名的方法

    python中使用sys模板和logging模块获取行号和函数名的方法

    这篇文章主要介绍了python中使用sys模板和logging模块获取行号和函数名的方法,需要的朋友可以参考下
    2014-04-04
  • python框架flask入门之路由及简单实现方法

    python框架flask入门之路由及简单实现方法

    这篇文章主要介绍了python框架flask入门路由及路由简单实现方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • Python函数的迭代器与生成器的示例代码

    Python函数的迭代器与生成器的示例代码

    这篇文章主要介绍了Python函数的迭代器与生成器的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • 使用python绘制温度变化雷达图

    使用python绘制温度变化雷达图

    这篇文章主要为大家介绍了使用python绘制温度变化雷达图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • 利用Python的pandas数据处理包将宽表变成窄表

    利用Python的pandas数据处理包将宽表变成窄表

    这篇文章主要介绍了利用Python的pandas数据处理包将宽表变成窄表,文章通过围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • Python合并Excel中sheet表的示例代码

    Python合并Excel中sheet表的示例代码

    这篇文章主要为大家详细介绍了如何利用Python实现将Excel中的五个表合成一个表,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11

最新评论