当前位置: 首页 > 编程笔记 >

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

潘慈
2023-03-14
本文向大家介绍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的SQLite接口来处理SQL数据库。python的SQLite API中的一个不错的功能是“上下文管理器”,即python的语句。我通常以以下方式执行查询: 使用上面的代码,如果我的查询修改了数据库并且忘记了运行,则上下文管理器在退出语句后自动为我运行它。它还可以很好地处理异常:如果在我提交任何内容之前发生异常,则数据库将回滚。 我现在正在使用该接口,该

  • 本文向大家介绍Python上下文管理器类和上下文管理器装饰器contextmanager用法实例分析,包括了Python上下文管理器类和上下文管理器装饰器contextmanager用法实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python上下文管理器类和上下文管理器装饰器contextmanager用法。分享给大家供大家参考,具体如下: 一. 什么是上下文管理器 上下文管理

  • 本文向大家介绍python 上下文管理器使用方法小结,包括了python 上下文管理器使用方法小结的使用技巧和注意事项,需要的朋友参考一下 上下文管理器最常用的是确保正确关闭文件, with 语句的基本语法, with expression [as variable]:     with-block expression是一个上下文管理器,其实现了enter和exit两个函数。当我们调用一个wit

  • 问题内容: 我不明白为什么无法在此示例中模拟NamedTemporaryFile.name: 测试结果在: 问题答案: 您设置的模拟错误:不是上下文管理器,而是 返回 了一个上下文管理器。将您的设置行替换为: 这样您的测试就可以了。

  • 问题内容: 在这个问题中,我定义了一个包含上下文管理器的上下文管理器。完成此嵌套的最简单的正确方法是什么?我最后打电话了。但是,在中,我很确定我必须调用finally块,以防引发异常。如果出现问题,是否应该设置type_,value和traceback参数?我检查了,但找不到任何实用程序来帮助解决此问题。 来自问题的原始代码: 问题答案: 创建上下文管理器的简单方法是使用。像这样: 然后使用。语句

  • 本文向大家介绍Python多个上下文管理器,包括了Python多个上下文管理器的使用技巧和注意事项,需要的朋友参考一下 示例 您可以同时打开多个内容管理器: 它与嵌套上下文管理器具有相同的效果: