Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将中间函数实现为协同路由或返回可等待项_Python_Python Asyncio - Fatal编程技术网

Python 将中间函数实现为协同路由或返回可等待项

Python 将中间函数实现为协同路由或返回可等待项,python,python-asyncio,Python,Python Asyncio,有两种实现中间函数的方法,它们位于可等待的创建和对象被等待的站点之间。一种实现使中间函数成为协同程序,其中可等待被等待等待;然后,用户在该协同程序上等待。另一种方法是将中间步骤编写为函数,创建Awaitable,并将其返回到发生await的站点。下面是一个例子 导入异步IO 从键入导入等待 异步def wait1()->无: 等待asyncio.sleep(1) def wait2()->可等待[无]: 返回asyncio.sleep(1) 异步def main(): 等待wait1() 等待等

有两种实现中间函数的方法,它们位于
可等待
的创建和对象被
等待
的站点之间。一种实现使中间函数成为协同程序,其中
可等待
等待
等待;然后,用户在该协同程序上等待。另一种方法是将中间步骤编写为函数,创建
Awaitable
,并将其返回到发生
await
的站点。下面是一个例子

导入异步IO
从键入导入等待
异步def wait1()->无:
等待asyncio.sleep(1)
def wait2()->可等待[无]:
返回asyncio.sleep(1)
异步def main():
等待wait1()
等待等待2()
asyncio.run(main())

这两种实现之间有什么区别?利与弊?性能差异?有没有行为上的差异?我正在制作许多这样的函数,并且希望做“正确”的事情。

目前使用的,
wait1
wait2
在功能上是等效的。调用时,两者都返回一个协同路由对象,即运行异步(协同路由)函数的结果。如果出现以下情况,则会产生差异:

  • 这些功能有副作用,并且
  • 他们返回的等待时间不是立即等待的
在这种情况下,对于
wait1
而言,副作用只有在等待之后才会发生,而对于
wait2
而言,副作用将在调用后立即发生

在大多数情况下,这没有什么区别,但有时是可以观察到的。例如,函数
run_in_executor
不能作为协同程序实现,因为当前实现是一个函数,它首先将接收到的可调用内容提交给执行器,然后创建并返回一个代理底层的。这允许API用户编写:

#我不在乎结果,只要提交就行了
loop.run_in_executor(无,我的_回调)
如果
run\u in\u executor
是一个协同程序,这将是不可操作的,在您等待它或将它传递给
create\u task
以运行它之前,不会提交任何内容

我正在做很多这样的功能,我想做“正确”的事情


为了清晰起见,我会尽可能使用协同程序。在不能使用协同程序的地方,比如lambda表达式,可以使用
wait1
wait2
之间的等价性。

正如当前使用的那样,
wait1
wait2
在功能上是等价的。调用时,两者都返回一个协同路由对象,即运行异步(协同路由)函数的结果。如果出现以下情况,则会产生差异:

  • 这些功能有副作用,并且
  • 他们返回的等待时间不是立即等待的
在这种情况下,对于
wait1
而言,副作用只有在等待之后才会发生,而对于
wait2
而言,副作用将在调用后立即发生

在大多数情况下,这没有什么区别,但有时是可以观察到的。例如,函数
run_in_executor
不能作为协同程序实现,因为当前实现是一个函数,它首先将接收到的可调用内容提交给执行器,然后创建并返回一个代理底层的。这允许API用户编写:

#我不在乎结果,只要提交就行了
loop.run_in_executor(无,我的_回调)
如果
run\u in\u executor
是一个协同程序,这将是不可操作的,在您等待它或将它传递给
create\u task
以运行它之前,不会提交任何内容

我正在做很多这样的功能,我想做“正确”的事情

为了清晰起见,我会尽可能使用协同程序。在不能使用协程的地方,比如lambda表达式,可以使用
wait1
wait2
之间的等价性