2024-06-01 04:16:26 发布
网友
从我所读到的内容来看,绝不应该使用扭曲的result对象的Deferred属性来访问延迟对象的值。我怀疑原因是
result
Deferred
AttributeError
是否曾经有过这样一种情况,即获得递延所得税结果的价值是适当的?有没有更好的方法来访问结果,将其分配给一个变量,或者在以后使用它,而不向延迟对象添加额外的回调?你知道吗
你的怀疑基本上是正确的。你知道吗
No result may not be available at the time of access (raises AttributeError)
Deferred的思想是,有些工作正在发生,在某个固定的时间内不会完成。当它完成的时候它就会完成。幸运的是,当它完成时,Deferred可以告诉您结果—这就是回调的目的。这意味着,如果没有使用回调,就无法知道工作何时完成。您可能太早检查并得到一个AttributeError(或者其他类型的失败,下面将对此进行详细介绍)。你可能检查得太晚,浪费了一些时间。你可以通过反复检查和处理错误来“修复”过早的情况。这称为“轮询”。Twisted的很大一部分是为了消除执行轮询的需要,因为轮询通常是不受欢迎的(代价很高)。解决“太迟”的唯一方法是更频繁地检查——这会使“太早”的情况更糟。你知道吗
The result may not be final at the time of access (i.e. not all callbacks have run)
Deferred提供的一个特性是,它允许在事件驱动编程中进行合成。您可以有一个执行某些任务并返回Deferred的单元。单元B可以执行一些任务,依赖于单元A并返回一些其他的Deferred。这样的构图可以是这样的:
d = Deferred() d_a = unit_a() def a_finished(result): d_b = unit_b(result) d_b.addCallback(d_final.callback) d_a.addCallback(a_finished)
在这个例子的执行过程中,d.result采用什么值?首先它是一个AttributeError,然后它是用unit_bDeferred调用的任何值。在这种情况下,您不会暴露出不完整或中间的结果,也不会有任何问题。然而,这种组合是笨拙的、冗长的和容易失败的(例如,它遗漏了错误传播和取消特性)。你知道吗
d.result
unit_b
编写Deferredapi的简单、惯用、受鼓励的方法是:
d = unit_a() d.addCallback(unit_b)
更容易写,更容易读,你得到的功能,如铁路式错误传播。你知道吗
在这种情况下,d.result有什么价值观呢?首先是一个AttributeError。然后,在unit_a完成之后,d.result是unit_b返回的Deferred。因此,如果你在这里查找,不仅没有最终结果,甚至没有实际值,反而有一个Deferred。只有在unit_b完成之后,d才会呈现unit_b的真实结果。你知道吗
unit_a
d
还有其他可能的序列。它们产生于其他的Deferred使用模式,这些使用模式不像上面的那样受欢迎,但它们肯定是可能的。例如,您可能有这样一个实现:
d = unit_a()
然后将d暴露给您的代码。在这一点之后,您可能需要执行以下操作:
d.addCallback(unit_b)
现在d.result从AttributeError到unit_a的结果,再到Deferred到unit_b的结果。上面提到的并不是Deferred的优秀用法,但是正如您所看到的,这是完全可能的。在这种情况下,如果您正在轮询d.result,那么您将不得不猜测非Deferred值是unit_a还是unit_b的结果。你知道吗
Is there ever a situation where it is appropriate to access the value of the result of the Deferred?
很难完全排除。当然,在Deferred本身的测试套件中有一些直接访问,这些访问可能是合法的。在其他一些与测试相关的工具中,这样访问result属性可能是合适的,但理想情况下,即使在那里也可以避免,或者测试库(比如Twisted的试用版)可以提供更好的工具来编写这类测试(例如试用版确实提供了successResultOf、failureResultOf、assertNoResult)。除此之外,我认为您应该非常仔细地研究result属性的任何用法,您可能会发现有一个更好的(更易维护、更不脆弱的)使用回调的解决方案。你知道吗
successResultOf
failureResultOf
assertNoResult
Is there a better way to access the result to assign it to a variable or use it later without adding additional callbacks to the Deferred?
访问结果的更好方法总是添加一个额外的回调。另一个答案表明,inlineCallbacks是一种使用回调的方法,它看起来不像使用回调,而且是许多人的首选。它可以让你做一个简单的分配到一个本地ret但是实现仍然使用Deferred.addCallback和相关的api。你知道吗
inlineCallbacks
Deferred.addCallback
我想这就是你要找的。使用inlinecallbacks,您可以访问结果,而无需编写回调。你知道吗
@inlineCallBacks def thingummy(): thing = yield makeSomeRequestResultingInDeferred() print(thing) # the result! hoorj!
https://twistedmatrix.com/documents/13.2.0/api/twisted.internet.defer.inlineCallbacks.html
你的怀疑基本上是正确的。你知道吗
Deferred
的思想是,有些工作正在发生,在某个固定的时间内不会完成。当它完成的时候它就会完成。幸运的是,当它完成时,Deferred
可以告诉您结果—这就是回调的目的。这意味着,如果没有使用回调,就无法知道工作何时完成。您可能太早检查并得到一个AttributeError
(或者其他类型的失败,下面将对此进行详细介绍)。你可能检查得太晚,浪费了一些时间。你可以通过反复检查和处理错误来“修复”过早的情况。这称为“轮询”。Twisted的很大一部分是为了消除执行轮询的需要,因为轮询通常是不受欢迎的(代价很高)。解决“太迟”的唯一方法是更频繁地检查——这会使“太早”的情况更糟。你知道吗Deferred
提供的一个特性是,它允许在事件驱动编程中进行合成。您可以有一个执行某些任务并返回Deferred
的单元。单元B可以执行一些任务,依赖于单元A并返回一些其他的Deferred
。这样的构图可以是这样的:在这个例子的执行过程中,
d.result
采用什么值?首先它是一个AttributeError
,然后它是用unit_b
Deferred
调用的任何值。在这种情况下,您不会暴露出不完整或中间的结果,也不会有任何问题。然而,这种组合是笨拙的、冗长的和容易失败的(例如,它遗漏了错误传播和取消特性)。你知道吗编写
Deferred
api的简单、惯用、受鼓励的方法是:更容易写,更容易读,你得到的功能,如铁路式错误传播。你知道吗
在这种情况下,
d.result
有什么价值观呢?首先是一个AttributeError
。然后,在unit_a
完成之后,d.result
是unit_b
返回的Deferred
。因此,如果你在这里查找,不仅没有最终结果,甚至没有实际值,反而有一个Deferred
。只有在unit_b
完成之后,d
才会呈现unit_b
的真实结果。你知道吗还有其他可能的序列。它们产生于其他的
Deferred
使用模式,这些使用模式不像上面的那样受欢迎,但它们肯定是可能的。例如,您可能有这样一个实现:然后将
d
暴露给您的代码。在这一点之后,您可能需要执行以下操作:现在
d.result
从AttributeError
到unit_a
的结果,再到Deferred
到unit_b
的结果。上面提到的并不是Deferred
的优秀用法,但是正如您所看到的,这是完全可能的。在这种情况下,如果您正在轮询d.result
,那么您将不得不猜测非Deferred
值是unit_a
还是unit_b
的结果。你知道吗很难完全排除。当然,在
Deferred
本身的测试套件中有一些直接访问,这些访问可能是合法的。在其他一些与测试相关的工具中,这样访问result
属性可能是合适的,但理想情况下,即使在那里也可以避免,或者测试库(比如Twisted的试用版)可以提供更好的工具来编写这类测试(例如试用版确实提供了successResultOf
、failureResultOf
、assertNoResult
)。除此之外,我认为您应该非常仔细地研究result
属性的任何用法,您可能会发现有一个更好的(更易维护、更不脆弱的)使用回调的解决方案。你知道吗访问结果的更好方法总是添加一个额外的回调。另一个答案表明,
inlineCallbacks
是一种使用回调的方法,它看起来不像使用回调,而且是许多人的首选。它可以让你做一个简单的分配到一个本地ret但是实现仍然使用Deferred.addCallback
和相关的api。你知道吗我想这就是你要找的。使用inlinecallbacks,您可以访问结果,而无需编写回调。你知道吗
@inlineCallBacks def thingummy(): thing = yield makeSomeRequestResultingInDeferred() print(thing) # the result! hoorj!
https://twistedmatrix.com/documents/13.2.0/api/twisted.internet.defer.inlineCallbacks.html
相关问题 更多 >
编程相关推荐