解决使用async def 的python语法无效

时间:2024-03-07 21:55:55

前言:最近在研究mock的使用,异步能不能实现,出现了一点点小坑,方便以后学习和查看,顺便记录一下

在学习asyncio之前,我们先来理清楚同步/异步的概念

·同步是指完成事务的逻辑,先执行第一个事务,如果阻塞了,会一直等待,直到这个事务完成,再执行第二个事务,顺序执行。。。

·异步是和同步相对的,异步是指在处理调用这个事务的之后,不会等待这个事务的处理结果,直接处理第二个事务去了,通过状态、通知、回调来通知调用者处理结果。

异步请求是在v3.3中引入Python的,如果你在v3.3之前运行Python(包括v2.X),你将不得不安装更新版本的Python。

只有当你运行Python 3.3:asyncio不是stdlib的一部分时,你需要从pypi手动安装它

pip install asyncio

asyncawait关键字是唯一有效的Python 3.5或更高版本。我使用的是Python 3.4,则需要对代码进行以下更改:

  1. 使用@asyncio.coroutine装饰器而不是async语句:
import asyncio

class File(object):

    def __init__(self, filename):
        self.filename = filename

    @classmethod
    def load(cls):
        return cls(filename="这个文件是从数据库获取的")

    @asyncio.coroutine
    @classmethod
    def load_async(cls):
        return cls(filename="这个文件是从数据库获取的")
  1. 使用yield from而不是await

以下是我的函数需要更改的示例(我使用的是3.4):

from automation.test.exercise1 import File
from unittest.mock import patch
import pytest
import asyncio

@patch(\'automation.test.exercise1.File.load\')
def test_load1( mock_load):
    mock_load.return_value = "直接mock返回值"
    assert File.load() == "直接mock返回值"

@asyncio.coroutine
@pytest.mark.asyncio
@patch(\'automation.test.exercise1.File.load_async\')
def test_load3(mock_load_async):
    mock_load_async.return_value=\'异步方法也能mock\'
    assert (yield from File.load_async() == "异步方法也能mock")



if __name__=="__main__":
    pytest.main([\'-sq\', \'exercise1.py\'])

在较新版本的Python 3中仍然支持上述语法,但建议使用awaitasync如果不需要支持Python 3.3-3.4。您可以参考此文档,这是一个简短的片段:

async def在Python 3.5中添加了协同程序的类型,如果不需要支持旧的Python版本,建议使用它。