异步上下文管理器 [英] Asynchronous context manager

查看:95
本文介绍了异步上下文管理器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个异步API ,我正在使用该API连接并将邮件发送到SMTP具有一些设置并拆除的服务器.因此,它非常适合使用Python 3的contextlib中的contextmanager.

I have an asynchronous API which I'm using to connect and send mail to an SMTP server which has some setup and tear down to it. So it fits nicely into using a contextmanager from Python 3's contextlib.

但是,我不知道是否有可能写,因为它们都使用生成器语法来写.

Though, I don't know if it's possible write because they both use the generator syntax to write.

这可能证明了这个问题(包含yield-base和async-await语法的混合,以演示异步调用和上下文管理器的yield之间的区别).

This might demonstrate the problem (contains a mix of yield-base and async-await syntax to demonstrate the difference between async calls and yields to the context manager).

@contextmanager
async def smtp_connection():
    client = SMTPAsync()
    ...

    try:
        await client.connect(smtp_url, smtp_port)
        await client.starttls()
        await client.login(smtp_username, smtp_password)
        yield client
    finally:
        await client.quit()

目前在python中是否可能发生这种情况?以及如何使用with as语句?如果没有,我可以通过另一种方式实现这一目标-也许使用旧样式的上下文管理器?

Is this kind of thing possible within python currently? and how would I use a with as statement if it is? If not is there a alternative way I could achieve this - maybe using the old style context manager?

推荐答案

在Python 3.7中,您将能够编写:

In Python 3.7, you'll be able to write:

from contextlib import asynccontextmanager

@asynccontextmanager
async def smtp_connection():
    client = SMTPAsync()
    ...

    try:
        await client.connect(smtp_url, smtp_port)
        await client.starttls()
        await client.login(smtp_username, smtp_password)
        yield client
    finally:
        await client.quit()

直到3.7发布,您可以为此使用 async_generator 软件包.在3.6上,您可以编写:

Until 3.7 comes out, you can use the async_generator package for this. On 3.6, you can write:

# This import changed, everything else is the same
from async_generator import asynccontextmanager

@asynccontextmanager
async def smtp_connection():
    client = SMTPAsync()
    ...

    try:
        await client.connect(smtp_url, smtp_port)
        await client.starttls()
        await client.login(smtp_username, smtp_password)
        yield client
    finally:
        await client.quit()

如果您想一直回到3.5,可以这样写:

And if you want to work all the way back to 3.5, you can write:

# This import changed again:
from async_generator import asynccontextmanager, async_generator, yield_

@asynccontextmanager
@async_generator      # <-- added this
async def smtp_connection():
    client = SMTPAsync()
    ...

    try:
        await client.connect(smtp_url, smtp_port)
        await client.starttls()
        await client.login(smtp_username, smtp_password)
        await yield_(client)    # <-- this line changed
    finally:
        await client.quit()

这篇关于异步上下文管理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆