Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 测试是否等待协同程序_Python_Python 3.x_Python Asyncio_Python 3.7 - Fatal编程技术网

Python 测试是否等待协同程序

Python 测试是否等待协同程序,python,python-3.x,python-asyncio,python-3.7,Python,Python 3.x,Python Asyncio,Python 3.7,我有一个连接到数据库的异步函数。目前 我的用户会: conn = await connect(uri, other_params) 我希望继续支持此功能,但希望另外允许将connect()用作上下文管理器: async with connect(uri, other_params) as conn: pass 这两种情况之间的区别在于,在第一种情况下,connect处于等待状态,而在第二种情况下则不是 在connect的主体中,是否可以判断是否等待协同程序 我目前在这方面的努力是基

我有一个连接到数据库的异步函数。目前 我的用户会:

conn = await connect(uri, other_params)
我希望继续支持此功能,但希望另外允许将
connect()
用作上下文管理器:

async with connect(uri, other_params) as conn:
     pass
这两种情况之间的区别在于,在第一种情况下,
connect
处于等待状态,而在第二种情况下则不是

connect
的主体中,是否可以判断是否等待协同程序


我目前在这方面的努力是基于。

我认为在您的示例中存在一个结构性问题

因此,首先您的示例需要等待
调用

@pytest.mark.asyncio
async def test_connect_with_context_manager():
    async with await connect("with context uri") as no_context:
        # Now it's open
        assert no_context.open

    # Now it's closed
    assert not no_context.open
但这里的问题是,
wait connect(“with context uri”)
的结果是一个
连接
,它甚至没有
\uuuuu aexit\uuu
方法


因此,我认为您应该彻底改变结构,将
connect
方法添加到
Connection
以实际建立连接,并在
MagicConnection
中,授权
连接的每个方法

以下是通过您提供的测试的代码:

import asyncio
import pytest
from functools import wraps


def connection_context_manager(func):
  @wraps(func)
  def wrapper(*args, **kwargs):

    class Wrapper:
        def __init__(self):
          self._conn = None

        async def __aenter__(self):
            self._conn = await func(*args, **kwargs)
            return self._conn

        async def __aexit__(self, *_):
          await self._conn.close()

        def __await__(self):
            return func(*args, **kwargs).__await__()  # https://stackoverflow.com/a/33420721/1113207
    return Wrapper()

  return wrapper
请注意,三种神奇的方法使我们能够同时创建对象可等待和异步上下文管理器


如果您有任何问题,请随时提问。

回答得很好!我建议不要每次调用decorator时都创建一个新类,因为类相对来说比较重,而且构造速度也比较慢。而且很容易避免它——只需在顶层定义
Wrapper
,将
func
传递给它的构造函数,并在需要的地方使用
self.\u func
。你和@user4815162342是我的英雄。这是好东西。事实上,我不知道有一个
\uuuuuuuuuuuuuuuuuuu
魔法。谢谢。@user4815162342的答案将详细显示