gpt4 book ai didi

python - 扭曲: `defer.execute` 和 `threads.deferToThread` 之间的区别

转载 作者:太空狗 更新时间:2023-10-29 20:57:08 25 4
gpt4 key购买 nike

twisted 中 defer.execute()threads.deferToThread() 有什么区别?两者都采用相同的参数 - 一个函数和调用它的参数 - 并返回一个 deferred ,它将与调用函数的结果一起触发。

threads 版本明确声明它将在线程中运行。但是,如果 defer 版本没有,那么调用它有什么意义呢?在 react 器中运行的代码永远不会阻塞,因此它调用的任何函数都必须不阻塞。在这一点上,你可以用 defer.succeed(f(*args, **kwargs)) 而不是 defer.execute(f, args, kwargs)相同的结果。

最佳答案

defer.execute 确实在同一个线程中以阻塞方式执行函数,你是正确的 defer.execute(f, args, kwargs) 一样defer.succeed(f(*args, **kwargs)) 除了 defer.execute 将返回一个回调,如果 function < strong>f 抛出异常。同时,在您的 defer.succeed 示例中,如果函数抛出异常,它会向外传播,这可能不是我们想要的。

为了便于理解,我将 defer.execute 的源代码粘贴在这里:

def execute(callable, *args, **kw):
"""Create a deferred from a callable and arguments.

Call the given function with the given arguments. Return a deferred which
has been fired with its callback as the result of that invocation or its
errback with a Failure for the exception thrown.
"""
try:
result = callable(*args, **kw)
except:
return fail()
else:
return succeed(result)

换句话说,defer.execute 只是将阻塞函数的结果作为延迟的快捷方式,然后您可以向其添加回调/错误返回。回调将以正常的链接语义触发。这似乎有点疯狂,但 Deferreds 可以在您添加回调之前“触发”并且回调仍将被调用。


所以要回答您的问题,为什么这有用?好吧,defer.execute 对于测试/模拟以及简单地将异步 api 与同步代码集成都很有用。

defer.maybeDeferred 也很有用,它调用函数,然后如果函数已经返回一个 deferred,则简单地返回它,否则函数类似于 defer.execute。当您编写一个 API,该 API 需要一个可调用对象,在调用时给您一个延迟,并且您还希望能够接受正常的阻塞函数。

例如,假设您有一个应用程序可以获取页面并用它做一些事情。而且,出于某种原因,您需要针对特定​​用例以同步方式运行它,例如在单次 crontab 脚本中,或响应 WSGI 应用程序中的请求,但仍保持相同的代码库。如果您的代码看起来像这样,则可以这样做:

from twisted.internet import defer
from twisted.web.client import getPage

def process_feed(url, getter=getPage):
d = defer.maybeDeferred(getter, url)
d.addCallback(_process_feed)

def _process_feed(result):
pass # do something with result here

要在没有反应堆的情况下在同步上下文中运行它,您可以传递一个替代的 getter 函数,如下所示:

from urllib2 import urlopen

def synchronous_getter(url):
resp = urlopen(url)
result = resp.read()
resp.close()
return result

关于python - 扭曲: `defer.execute` 和 `threads.deferToThread` 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3686608/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com