如何使用Python异步之上下文管理器

目录
  • 正文
  • 1. 什么是异步上下文管理器
    • 1.1. Context Manager
    • 1.2. Asynchronous Context Manager
  • 2. 如何使用异步上下文管理器
    • 2.1. 定义
    • 2.2. 使用
  • 3. 异步上下文管理器和“异步”示例

正文

上下文管理器是一种 Python 构造,它提供了一个类似 try-finally 的环境,具有一致的接口和方便的语法,例如通过“with”表达。

它通常与资源一起使用,确保在我们完成资源后始终关闭或释放资源,无论资源的使用是成功还是因异常而失败。

Asyncio 允许我们开发异步上下文管理器。

我们可以通过定义一个将 aenter() 和 aexit() 方法实现为协程的对象来在 asyncio 程序中创建和使用异步上下文管理器。

1. 什么是异步上下文管理器

异步上下文管理器是一个实现了 aenter() 和 aexit() 方法的 Python 对象。

在我们深入了解异步上下文管理器的细节之前,让我们回顾一下经典的上下文管理器。

1.1. Context Manager

上下文管理器是一个 Python 对象,它实现了 enter() 和 exit() 方法。

  • enter() 方法定义了块开头发生的事情,例如打开或准备资源,如文件、套接字或线程池。
  • exit() 方法定义退出块时发生的情况,例如关闭准备好的资源。

通过“with”表达式使用上下文管理器。通常,上下文管理器对象是在“with”表达式的开头创建的,并且会自动调用 enter() 方法。内容的主体通过命名的上下文管理器对象使用资源,然后 aexit() 方法在块退出时自动调用,通常或通过异常。

...
# open a context manager
with ContextManager() as manager:
	# ...
# closed automatically

这反映了 try-finally 表达式。

...
# create the object
manager = ContextManager()
try:
	manager.__enter__()
	# ...
finally:
	manager.__exit__()

1.2. Asynchronous Context Manager

“PEP 492 – Coroutines with async and await syntax”引入了异步上下文管理器。

它们提供了一个上下文管理器,可以在进入和退出时挂起。

aenteraexit 方法被定义为协同程序,由调用者等待。这是使用“async with”表达式实现的。

因此,异步上下文管理器只能在 asyncio 程序中使用,例如在调用协程中。

  • 什么是“async with”

“async with”表达式用于创建和使用异步上下文管理器。它是“with”表达式的扩展,用于异步程序中的协程。

“async with”表达式就像用于上下文管理器的“with”表达式,除了它允许在协同程序中使用异步上下文管理器。

为了更好地理解“async with”,让我们仔细看看异步上下文管理器。async with 表达式允许协程创建和使用上下文管理器的异步版本。

...
# create and use an asynchronous context manager
async with AsyncContextManager() as manager:
	# ...

这相当于:

...
# create or enter the async context manager
manager = await AsyncContextManager()
try:
	# ...
finally:
	# close or exit the context manager
	await manager.close()

请注意,我们正在实现与传统上下文管理器大致相同的模式,只是创建和关闭上下文管理器涉及等待协程。

这会暂停当前协程的执行,调度一个新的协程并等待它完成。因此,异步上下文管理器必须实现必须通过 async def 表达式定义的 aenter() 和 aexit() 方法。这使得它们自己协程也可能等待。

2. 如何使用异步上下文管理器

在本节中,我们将探讨如何在我们的 asyncio 程序中定义、创建和使用异步上下文管理器。

2.1. 定义

我们可以将异步上下文管理器定义为实现 aenter() 和 aexit() 方法的 Python 对象。

重要的是,这两种方法都必须使用“async def”定义为协程,因此必须返回可等待对象。

# define an asynchronous context manager
class AsyncContextManager:
    # enter the async context manager
    async def __aenter__(self):
        # report a message
        print('>entering the context manager')
    # exit the async context manager
    async def __aexit__(self, exc_type, exc, tb):
        # report a message
        print('>exiting the context manager')

因为每个方法都是协程,所以它们本身可能等待协程或任务。

# define an asynchronous context manager
class AsyncContextManager:
    # enter the async context manager
    async def __aenter__(self):
        # report a message
        print('>entering the context manager')
        # block for a moment
        await asyncio.sleep(0.5)
    # exit the async context manager
    async def __aexit__(self, exc_type, exc, tb):
        # report a message
        print('>exiting the context manager')
        # block for a moment
        await asyncio.sleep(0.5)

2.2. 使用

通过“async with”表达式使用异步上下文管理器。这将自动等待进入和退出协程,根据需要暂停调用协程。

...
# use an asynchronous context manager
async with AsyncContextManager() as manager:
	# ...

因此,“async with”表达式和异步上下文管理器更普遍地只能在 asyncio 程序中使用,例如在协程中。

现在我们知道如何使用异步上下文管理器,让我们看一个有效的例子。

3. 异步上下文管理器和“异步”示例

我们可以探索如何通过“async with”表达式使用异步上下文管理器。

在这个例子中,我们将更新上面的例子,以正常方式使用上下文管理器。

我们将使用“async with”表达式,并在一行中创建并进入上下文管理器。这将自动等待 enter 方法。

然后我们可以在内部块中使用管理器。在这种情况下,我们将只报告一条消息。

退出内部块将自动等待上下文管理器的退出方法。将这个例子与前面的例子进行对比,可以看出“async with”表达式在 asyncio 程序中为我们做了多少繁重的工作。

# SuperFastPython.com
# example of an asynchronous context manager via async with
import asyncio
# define an asynchronous context manager
class AsyncContextManager:
    # enter the async context manager
    async def __aenter__(self):
        # report a message
        print('>entering the context manager')
        # block for a moment
        await asyncio.sleep(0.5)
    # exit the async context manager
    async def __aexit__(self, exc_type, exc, tb):
        # report a message
        print('>exiting the context manager')
        # block for a moment
        await asyncio.sleep(0.5)
# define a simple coroutine
async def custom_coroutine():
    # create and use the asynchronous context manager
    async with AsyncContextManager() as manager:
        # report the result
        print(f'within the manager')
# start the asyncio program
asyncio.run(custom_coroutine())

运行示例首先创建 main() 协程并将其用作 asyncio 程序的入口点。

main() 协程运行并在“async with”表达式中创建我们的 AsyncContextManager 类的实例。

该表达式自动调用 enter 方法并等待协程。报告一条消息,协程暂时阻塞。

main() 协程恢复并执行上下文管理器的主体,打印一条消息。

块退出,自动等待上下文管理器的退出方法,报告消息并休眠片刻。

这突出了 asyncio 程序中异步上下文管理器的正常使用模式。

>entering the context manager
within the manager
>exiting the context manager

以上就是如何使用Python异步之上下文管理器的详细内容,更多关于Python异步之上下文管理器的资料请关注我们其它相关文章!

(0)

相关推荐

  • Python 异步之如何启动获取事件循环

    目录 1. 什么是 Asyncio 事件循环 2. 如何启动和获取事件循环 3. 什么是事件循环对象 4. 为什么要访问事件循环 1. 什么是 Asyncio 事件循环 asyncio 程序的核心是事件循环.在本节中,我们将花点时间看一下 asyncio 事件循环 事件循环是用于在单个线程中执行协程的环境.事件循环是异步程序的核心. 它做了很多事情,例如: 执行协程. 执行回调. 执行网络输入/输出. 运行子进程. 事件循环是一种常见的设计模式,并且由于在 JavaScript 中的使用而在最近

  • Python中如何创建和运行异步任务详解

    目录 正文 1. 什么是异步任务 2. 如何创建任务 2.1. 高级 API 2.2. 低级 API 3. 任务何时运行? 正文 您可以从 asyncio 程序中的协程创建任务对象.任务提供独立调度和运行的协程的句柄,并允许查询.取消任务,以及稍后检索结果和异常.异步事件循环管理任务.因此,所有协程都成为事件循环中的任务并作为任务进行管理. 让我们仔细看看 asyncio 任务. 1. 什么是异步任务 异步任务是一个调度并独立运行 asyncio 协程的对象.它提供了一个调度协程的句柄,asyn

  • Python 异步等待任务集合

    目录 正文 1. 什么是 asyncio.wait() 2. 如何使用 asyncio.wait() 3. 等待所有任务的示例 正文 我们可以通过 asyncio.wait() 函数等待异步任务完成.可以等待不同的条件,例如所有任务完成.第一个任务完成以及第一个任务因异常而失败. 让我们仔细看看. 1. 什么是 asyncio.wait() asyncio.wait() 函数可用于等待一组异步任务完成.回想一下,asyncio 任务是包装协程的 asyncio.Task 类的一个实例.它允许独立

  • Python 异步之如何获取当前和正在运行任务详解

    目录 正文 1. 如何获取当前任务 2. 如何获取所有任务 正文 我们可以反省在 asyncio 事件循环中运行的任务.这可以通过为当前运行的任务和所有正在运行的任务获取一个 asyncio.Task 对象来实现. 1. 如何获取当前任务 我们可以通过 asyncio.current_task() 函数获取当前任务.此函数将为当前正在运行的任务返回一个任务对象. ... # get the current task task = asyncio.current_task() 传递给 asynci

  • Python 异步如何使用等待有时间限制协程

    目录 正文 1. 什么是 Asyncio wait_for() 2. 如何使用 Asyncio wait_for() 3. 带有超时的 Asyncio wait_for() 示例 正文 我们可以使用 asyncio.wait_for() 函数等待 asyncio 任务或协程超时完成.如果在任务完成之前超时已过,任务将被取消. 1. 什么是 Asyncio wait_for() asyncio.wait_for() 函数允许调用者等待 asyncio 任务或协程超时完成.如果没有指定超时,wait

  • Python异步之迭代器如何使用详解

    目录 正文 1. 什么是异步迭代器 1.1. Iterators 1.2. Asynchronous Iterators 2. 什么是“async for”循环? 3. 如何使用异步迭代器 4. 异步迭代器示例 正文 迭代是 Python 中的基本操作.我们可以迭代列表.字符串和所有其他结构. Asyncio 允许我们开发异步迭代器.我们可以通过定义一个实现 aiter() 和 anext() 方法的对象来在 asyncio 程序中创建和使用异步迭代器. 1. 什么是异步迭代器 异步迭代器是一个

  • Python 异步之在 Asyncio中如何运行阻塞任务详解

    目录 正文 1. 阻塞任务 2. 如何运行阻塞任务 3. 实例 正文 阻塞任务是阻止当前线程继续进行的任务. 如果在 asyncio 程序中执行阻塞任务,它会停止整个事件循环,从而阻止任何其他协程继续进行. 我们可以通过 asyncio.to_thread() 和 loop.run_in_executor() 函数在 asyncio 程序中异步运行阻塞调用. 1. 阻塞任务 asyncio的重点是异步编程和非阻塞IO.然而,我们经常需要在 asyncio 应用程序中执行阻塞函数调用. 这可能有很

  • 如何使用Python异步之上下文管理器

    目录 正文 1. 什么是异步上下文管理器 1.1. Context Manager 1.2. Asynchronous Context Manager 2. 如何使用异步上下文管理器 2.1. 定义 2.2. 使用 3. 异步上下文管理器和“异步”示例 正文 上下文管理器是一种 Python 构造,它提供了一个类似 try-finally 的环境,具有一致的接口和方便的语法,例如通过“with”表达. 它通常与资源一起使用,确保在我们完成资源后始终关闭或释放资源,无论资源的使用是成功还是因异常而

  • python内置模块之上下文管理contextlib

    Python中当我们们打开文本时,通常会是用with语句,with语句允许我们非常方便的使用资源,而不必担心资源没有关闭. with open('/path/filename', 'r') as f: f.read() 然而,并不是只有open()函数返回fp对象才能使用 with 语句.实际上,任何对象,只要正确实现上下文管理,就可以使用with语句. 实现上下文管理是通过 __enter__ 和 __exit__ 这两个方法实现的.例如,下面的class实现了这两个方法: class Que

  • Python深入学习之上下文管理器

    上下文管理器(context manager)是Python2.5开始支持的一种语法,用于规定某个对象的使用范围.一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存).它的语法形式是with...as... 关闭文件 我们会进行这样的操作:打开文件,读写,关闭文件.程序员经常会忘记关闭文件.上下文管理器可以在不需要文件的时候,自动关闭文件. 下面我们看一下两段程序: 复制代码 代码如下: # without context manager f = open("new.t

  • Python with语句上下文管理器两种实现方法分析

    本文实例讲述了Python with语句上下文管理器.分享给大家供大家参考,具体如下: 在编程中会经常碰到这种情况:有一个特殊的语句块,在执行这个语句块之前需要先执行一些准备动作:当语句块执行完成后,需要继续执行一些收尾动作.例如,文件读写后需要关闭,数据库读写完毕需要关闭连接,资源的加锁和解锁等情况. 对于这种情况python提供了上下文管理器(Context Manager)的概念,可以通过上下文管理器来定义/控制代码块执行前的准备动作,以及执行后的收尾动作. 一.为何使用上下文管理器 1.

  • Python上下文管理器类和上下文管理器装饰器contextmanager用法实例分析

    本文实例讲述了Python上下文管理器类和上下文管理器装饰器contextmanager用法.分享给大家供大家参考,具体如下: 一. 什么是上下文管理器 上下文管理器是在Python2.5之后加入的功能,可以在方便的需要的时候比较精确地分配和释放资源, with便是上下文管理器的最广泛的应用, 比如: with open("test/test.txt","w") as f: f.write("hello") 这上会比使用try:...finall

  • python爬虫模块URL管理器模块用法解析

    这篇文章主要介绍了python爬虫模块URL管理器模块用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 URL管理器模块 一般是用来维护爬取的url和未爬取的url已经新添加的url的,如果队列中已经存在了当前爬取的url了就不需要再重复爬取了,另外防止造成一个死循环.举个例子 我爬www.baidu.com 其中我抓取的列表中有music.baidu.om,然后我再继续抓取该页面的所有链接,但是其中含有www.baidu.com,可以想

  • python小白学习包管理器pip安装

    pip对于使用python的朋友并不陌生,当你想安装python模块的时候一定会首先想到它.pip 是一个安装和管理 Python 包的工具 , 是 easy_install 的一个替换品. 今天来说一下,pip的安装方法. 方法一:脚本安装 $ wget https://bootstrap.pypa.io/get-pip.py $ [sudo] python get-pip.py 方法二:源码安装: $ curl -O https://pypi.python.org/packages/sour

  • python爬虫中url管理器去重操作实例

    当我们需要有一批货物需要存放时,最好的方法就是有一个仓库进行保管.我们可以把URL管理器看成一个收集了数据的大仓库,而下载器就是这个仓库货物的搬运者.关于下载器的问题,我们暂且不谈.本篇主要讨论的是在url管理器中,我们遇到重复的数据应该如何识别出来,避免像仓库一样过多的囤积相同的货物.听起来是不是很有意思,下面我们一起进入今天的学习. URL管理器到底应该具有哪些功能? URL下载器应该包含两个仓库,分别存放没有爬取过的链接和已经爬取过的链接. 应该有一些函数负责往上述两个仓库里添加链接 应该

  • Python编程ContextManager上下文管理器讲解

    目录 什么是上下文管理器 官方解释 简单一句话 __enter__(self) __exit__(self, exc_type, exc_value, exc_traceback) 有哪些常见上下文管理器? 打开文件 拆分了解 执行顺序 自定义上下文管理器 基于类实现上下文管理器 总结 基于生成器实现上下文管理器 总结 with 语句的教程 什么是上下文管理器 官方解释 上下文管理器是一个对象它定义了在执行 with 语句时要建立的运行时上下文上下文管理器处理进入和退出所需的运行时上下文以执行代

  • 深入学习Python中的上下文管理器与else块

    前言 本文主要个大家介绍了关于Python上下文管理器与else块的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 在开始之前,我们先来看看下面这段话: 最终,上下文管理器可能几乎与子程序(subroutine)本身一样重要.目前,我们只了解了上下文管理器的皮毛--Basic 语言有with 语句,而且很多语言都有.但是,在各种语言中 with 语句的作用不同,而且做的都是简单的事,虽然可以避免不断使用点号查找属性,但是不会做事前准备和事后清理.不要觉得名字一样,就意

随机推荐