sys:1:RuntimeWarning:从未等待协程 [英] sys:1: RuntimeWarning: coroutine was never awaited

查看:1730
本文介绍了sys:1:RuntimeWarning:从未等待协程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个请求处理程序,以帮助我以异步模式发送请求。当我用Ctrl + D或exit()关闭python终端时提示它

I am trying to write a request handler to help me send request in async mode. It prompt when I close the python terminal with Ctrl+D or exit()

它显示 sys:1:RuntimeWarning:从未等待协程

import asyncio
import urllib.request
import json 

class RequestHandler:
    def SendPostRequest(method="post",url=None, JsonFormatData={}):
        # Encode JSON
        data =json.dumps(JsonFormatData).encode('utf8')
        # Config Request Header
        req = urllib.request.Request(url)
        req.add_header('Content-Type', 'application/json')      
        # Send request and wait the response
        response = urllib.request.urlopen(req,data=data)    
        return response 

    async def AsyncSend(method="post",url=None, JsonFormatData=None):
        if method == "post":
            loop = asyncio.get_event_loop()
            task = loop.create_task(SendPostRequest(method="post",url=url,JsonFormatData=JsonFormatData))

###################################
# Example
##### In main python terminal, i run like this:
# from RequestHandler import * 
# RequestHandler.AsyncSend(method="post",url="xxxxxx", JsonFormatData={'key':'value'} )

当我单击Ctrl + D时,

When I Click Ctrl+D , it prompted

sys:1: RuntimeWarning: coroutine 'RequestHandler.AsyncSend' was never awaited

我会忽略它吗?我不想呼叫等待,因为我不在乎过程是否成功。

Is that I shall ignore it? I don't wanna call await, as i don't care if the process is success or not.

在此链接中的 https:// xinhuang.github.io/posts/2017-07-31-common-mistakes-using-python3-asyncio.html ,它表示要在不等待的情况下执行异步任务,请使用loop.create_task()与loop.run_until_complete(),那么,那是错的吗?

In this link "https://xinhuang.github.io/posts/2017-07-31-common-mistakes-using-python3-asyncio.html", it said that "To execute an asynchronous task without await, use loop.create_task() with loop.run_until_complete()", is that wrong then?

推荐答案

我认为您将JS异步API与Python混淆了。在Python中,当您调用协程函数时,它会返回协程(类似于武装发生器),但不会在事件循环中对其进行调度。 (即不运行/使用它)

I think you're confusing JS async API with Python's. In Python, when you call a coroutine function it returns a coroutine (similar to an armed generator) but doesn't schedule it in the event loop. (i.e. doesn't run/consume it)

您有两个选择:

1)您可以等待通过 await 或通过获得的较旧的收益。

1) You can await it via await or the older yield from.

2)您可以 asyncio.create_task(coroutine_function())。这等效于在JS中调用promise而不给它提供处理程序或等待它。

2) You can asyncio.create_task(coroutine_function()). This is the equivalent of calling a promise in JS without giving it a handler or awaiting it.

您所看到的警告是告诉您协程未运行。

The warning you're seeing is telling you that the coroutine didn't run. it was only created, but not consumed.

对于您的代码,有两个错误。首先urllib是一个阻塞库,您不能从中创建任务,也不能异步运行它,请查看 aiohttp.ClientSession

As to your code, there are two errors. First urllib is a blocking library, you can't create a task from it, neither can it be ran asynchronously, take a look at aiohttp.ClientSession instead.

第二,您看到的警告可能是由于您同步调用 AsyncSend 而引起的(没有等待它)。同样,在JS中这可能很好,因为JS中的所有内容都是异步的。在Python中,应该使用上面提到的两种主要方法之一。

Second, the warning you're seeing is probably caused by you calling AsyncSend synchronously (without awaiting it). Again, in JS this would probably be fine, as everything in JS is async. In Python, you should use one of the two main methods I mentioned above.

如果坚持使用阻塞库,则可以在其他线程上运行它,以便您不会阻止事件循环。正如Cloudomation所提到的,要做到这一点。您应该使用 asyncio.run_in_executor(无,lambda:your_urllib_function())

If you insist on using a blocking library, you can run it on a different thread so that you don't block the event loop. As Cloudomation mentioned, to do this. you should use asyncio.run_in_executor(None, lambda: your_urllib_function())

这篇关于sys:1:RuntimeWarning:从未等待协程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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