草庐IT

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

coder 2023-08-21 原文

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/

有关python - 扭曲: `defer.execute` 和 `threads.deferToThread` 之间的区别的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  3. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  4. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  5. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  6. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  7. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  8. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  9. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  10. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

随机推荐