Python aiohttp:app-dict中的单音实例VS-contextvars VS-globals VS-DI

Python aiohttp:app-dict中的单音实例VS-contextvars VS-globals VS-DI,python,dependency-injection,python-asyncio,aiohttp,python-contextvars,Python,Dependency Injection,Python Asyncio,Aiohttp,Python Contextvars,让我们假设在单个请求中有下一个链: some_view->coro_0->coro_1->coro_2->coro_3->coro_4 假设coro_2应该执行redis调用,coro_3-数据库查询和coro_4db和redis调用 根据所有教程等,正确的方法是在函数签名中声明redis_pool和db_engine,例如 异步def coro_2(db_引擎:引擎, redis_池:redis, arg_0:int, arg_1:str, ...) 但是在这种情况下,对于coro_0和co

让我们假设在单个请求中有下一个链:

some_view->coro_0->coro_1->coro_2->coro_3->coro_4

假设
coro_2
应该执行redis调用,
coro_3
-数据库查询和
coro_4
db和redis调用

根据所有教程等,正确的方法是在函数签名中声明
redis_pool
db_engine
,例如

异步def coro_2(db_引擎:引擎,
redis_池:redis,
arg_0:int,
arg_1:str,
...)
但是在这种情况下,对于
coro_0
coro_1
来说,这些变量实际上是不可用的,它们的唯一目的是将它们传递给下一个协同程序。通常,当存在其他arg和更多类似实例时(例如aws客户端、http客户端等),签名会变得太大(?)

我发现的另一个解决方案是contextvars,我声明了一个中间件,它设置了一个
db_引擎
,例如:

#声明CV
db_引擎:引擎=ContextVar('db_引擎')
@中间件
异步定义上下文变量中间件(处理程序、请求):
引擎=request.config_dict['db']
db_引擎组(引擎)
...
#在合作项目中:
engine=db_engine.get()
使用engine.acquire()作为连接:
...
这种方法的问题在于,这些变量与“上下文”无关,因为它们是静态的,并且在请求之间不会改变。在我看来,对每个请求进行额外的
set
调用是多余的

第三种解决方案-使用依赖项注入模式和库,如下所示: 但对我来说,这似乎是一种非蟒蛇式的方式

第四,使用singleton类并在需要的地方导入它

尽管这四种方法都有效——但我仍然不确定哪一种是“正确的”