我有一个asyncio项目。它有几个模块。他们中的许多人需要访问一些全局变量,例如:
1. aiohttp ClientSession()
对象,因为根据aiohttp文档,我应该避免为每个请求创建一个新的ClientSession。
2.异步套接字,即我使用reader, writer
创建的asyncio.open_connection()
。我想保持持久的连接。
3.事件循环,我使用asyncio.get_event_loop()
共享此类变量的最佳实践是什么?
我想创建一个globals.py
模块,它将定义这些变量。
问题是我无法在globals模块中为async with
对象使用ClientSession
语法。
对于套接字,我必须在异步def中以某种方式定义它,所以我不能在模块级别公开它。
并且,明智地进行测试-每个模块都应定义一个全局变量,例如:
loop = asyncio.get_event_loop()
或者,最好将事件循环传递给模块,例如在类__init__
中)?
答案 0 :(得分:0)
没有必要使用全局变量。而是,创建一个存储“全局”数据的类,并在该类上使用function方法。例如:
class Operation:
def __init__(self):
self._http = aiohttp.ClientSession()
async def open(self):
self._reader, self._writer = \
await asyncio.open_connection(<host>, <port>)
# ... more methods ...
async def close(self):
await self._http.close()
self._writer.close()
await self._writer.wait_closed()
这有几个优点:
Operation
实例即可。Operation
实例。在适当的位置,您的main
协程应如下所示:
async def main():
op = Operation()
await op.open()
try:
await op.do_something()
...
finally:
await op.close()
asyncio.run(main())
#or asyncio.get_event_loop().run_until_complete(main())
请注意,事件循环不存储在对象上或以任何方式传递给对象。这是因为始终可以使用asyncio.get_event_loop()
获得事件循环,当从协程调用该事件循环时,可以保证返回当前正在运行的循环。