问题描述
import asyncio
import aiohttp
import atexit
class Session:
def __init__(self):
self._session = aiohttp.ClientSession()
atexit.register(self._close_session)
async def get(self,url):
response = await self._session.request("GET",url)
return await response.json()
def _close_session(self):
asyncio.run(self._session.close())
async def pullit():
print(await session.get("https://raw.communitydragon.org/latest/game/data/characters/aatrox/aatrox.bin.json"))
session = Session()
asyncio.run(pullit()) # THIS THROWS: Timeout context manager should be used inside a task
asyncio.get_event_loop().run_until_complete(pullit()) #THIS RUNS OK
这在self._session.request
的{{1}}行上引发了异常,我已经搜索了其他答案,但仍然给出相同的错误。
问题:此错误的原因是什么?如果我想打开一个持续一个程序生命周期的会话,并且需要在一个类中(强制性)定义它,那怎么办?
其他:目前,我正在使用Timeout context manager should be used inside a task
在程序结束时关闭会话(请参见上面的代码),这是一种好的方式?如果没有,什么是更好的做法
更新:我找到了解决方案,它使用了atexit
,但与上面的asyncio.get_event_loop().run_until_complete(...)
不同吗?为什么一个人都可以毫无问题地运行,而3.7+ asyncio.run()
却没有运行?
更新2:我最终得到了以下代码:
asyncio.run()
#runner.py
import aiohttp
import asyncio
class Runner:
def __init__(self,coro):
self.coro = coro
async def run(self):
session = aiohttp.ClientSession()
client.start_session(session)
await self.coro
client.close_session()
await session.close()
def run(coro):
runner = Runner(coro)
return asyncio.run(runner.run())
#client.py
class Client:
def __init__(self):
self._session = None
async def get(self,url)
return await response.json()
def start_session(self,session):
self._session = session
def close_session(self):
self._session = None
好的,这一切都运行了,但是运行之后,它又抛出了我from .runner import run
from .client import Client
client = Client()
async def pullit():
print(await client.get("https://raw.communitydragon.org/latest/game/data/characters/aatrox/aatrox.bin.json"))
run(pullit())
,我从没关闭过循环。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)