Python 如何调用类中包含的异步函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42009202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 21:06:43  来源:igfitidea点击:

How to call a async function contained in a class?

pythonwebsocketpython-asyncio

提问by harrison4

Based on this answerI want to build an async websoket client in a class which would be imported from another file:

基于这个答案,我想在一个从另一个文件导入的类中构建一个异步 websoket 客户端:

#!/usr/bin/env python3

import sys, json
import asyncio
from websockets import connect

class EchoWebsocket:
    def __await__(self):
        # see: https://stackoverflow.com/a/33420721/1113207
        return self._async_init().__await__()

    async def _async_init(self):
        self._conn = connect('wss://ws.binaryws.com/websockets/v3')
        self.websocket = await self._conn.__aenter__()
        return self

    async def close(self):
        await self._conn.__aexit__(*sys.exc_info())

    async def send(self, message):
        await self.websocket.send(message)

    async def receive(self):
        return await self.websocket.recv()

class mtest:
    async def start(self):
        try:
            self.wws = await EchoWebsocket()
        finally:
            await self.wws.close()

    async def get_ticks(self):
        await self.wws.send(json.dumps({'ticks_history': 'R_50', 'end': 'latest', 'count': 1}))
        return await self.wws.receive()

if __name__ == '__main__':
    a = mtest()
    loop = asyncio.get_event_loop()
    loop.run_until_complete(a.start())

And I import it in main.py, where I have the following:

我将它导入 ,在main.py那里我有以下内容:

from testws import *

a = mtest()
print (a.get_ticks())
print ("this will be printed after the ticks")

But it retrieves me the following error:

但它检索我以下错误:

root@ubupc1:/home/dinocob# python3 test.py
<coroutine object hello.get_ticks at 0x7f13190a9200>
test.py:42: RuntimeWarning: coroutine 'mtest.get_ticks' was never awaited
  print (a.get_ticks())
this will be printed after the ticks

What's is going on here? Why I'm not able to access mtest.get_ticks if it has the asyncword at the begining of def?

这是怎么回事?如果 mtest.get_ticks 开头有async单词,为什么我无法访问它def

采纳答案by harrison4

Finally I could find the right way to do it (special thanks to @dirn)

最后我找到了正确的方法(特别感谢@dirn

#!/usr/bin/env python3

import sys, json
import asyncio
from websockets import connect

class EchoWebsocket:
    async def __aenter__(self):
        self._conn = connect('wss://ws.binaryws.com/websockets/v3')
        self.websocket = await self._conn.__aenter__()        
        return self

    async def __aexit__(self, *args, **kwargs):
        await self._conn.__aexit__(*args, **kwargs)

    async def send(self, message):
        await self.websocket.send(message)

    async def receive(self):
        return await self.websocket.recv()

class mtest:
    def __init__(self):
        self.wws = EchoWebsocket()
        self.loop = asyncio.get_event_loop()

    def get_ticks(self):
        return self.loop.run_until_complete(self.__async__get_ticks())

    async def __async__get_ticks(self):
        async with self.wws as echo:
            await echo.send(json.dumps({'ticks_history': 'R_50', 'end': 'latest', 'count': 1}))
            return await echo.receive()

And this in main.py:

这在 main.py 中:

from testws import *

a = mtest()

foo = a.get_ticks()
print (foo)

print ("async works like a charm!")

foo = a.get_ticks()
print (foo)

This is the output:

这是输出:

root@ubupc1:/home/dinocob# python3 test.py
{"count": 1, "end": "latest", "ticks_history": "R_50"}
async works like a charm!
{"count": 1, "end": "latest", "ticks_history": "R_50"}

Any tip to improve it is welcomed! ;)

欢迎任何改进它的提示!;)