当我不需要 yield return 值时,@defer.inlineCallbacks 是什么意思?
What does @defer.inlineCallbacks mean when I don't need yield return a value?
在scrapy.core.engine
ExecutionEngine 方法启动
@defer.inlineCallbacks
def start(self):
"""Start the execution engine"""
assert not self.running, "Engine already running"
self.start_time = time()
yield self.signals.send_catch_log_deferred(signal=signals.engine_started)
self.running = True
self._closewait = defer.Deferred()
yield self._closewait
为什么不直接使用 self.signals.send_catch_log_deferred(signal=signals.engine_started)
而是使用 yield 呢?
Why don't use self.signals.send_catch_log_deferred(signal=signals.engine_started)
directly but instead of a yield ?
因为 send_catch_log_deferred
return 是一个 Deferred
对象。如果你想避免在那里出现 yield
,那么你应该使用 send_catch_log
,但使用 send_catch_log_deferred
的目的是让听众能够听到 return Deferred
对象。
使用 send_catch_log
的信号无法 return Deferred
对象,因此它们不允许执行异步操作。
编辑:有关 inlineCallbacks
的详细介绍,请参阅:http://krondo.com/?p=2441
@defer.inlineCallbacks 期望装饰函数是一个生成器函数并且在装饰函数内调用生成器函数(甚至返回一个)不会生成函数,生成器函数。调查:
def gen():
yield 1
def func(): return gen
import dis
dis.dis(gen)
2 0 LOAD_CONST 1 (1)
3 YIELD_VALUE
4 POP_TOP
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
dis.dis(func)
1 0 LOAD_GLOBAL 0 (gen)
3 RETURN_VALUE
import inspect
inspect.isgeneratorfunction(gen)
True
inspect.isgeneratorfunction(func)
False
所以满足 @defer.inlineCallbacks 的唯一方法是 yield 从 self.signals.send_catch_log_deferred(signal= signals.engine_started) 或来自其他地方。
在scrapy.core.engine
ExecutionEngine 方法启动
@defer.inlineCallbacks
def start(self):
"""Start the execution engine"""
assert not self.running, "Engine already running"
self.start_time = time()
yield self.signals.send_catch_log_deferred(signal=signals.engine_started)
self.running = True
self._closewait = defer.Deferred()
yield self._closewait
为什么不直接使用 self.signals.send_catch_log_deferred(signal=signals.engine_started)
而是使用 yield 呢?
Why don't use
self.signals.send_catch_log_deferred(signal=signals.engine_started)
directly but instead of a yield ?
因为 send_catch_log_deferred
return 是一个 Deferred
对象。如果你想避免在那里出现 yield
,那么你应该使用 send_catch_log
,但使用 send_catch_log_deferred
的目的是让听众能够听到 return Deferred
对象。
使用 send_catch_log
的信号无法 return Deferred
对象,因此它们不允许执行异步操作。
编辑:有关 inlineCallbacks
的详细介绍,请参阅:http://krondo.com/?p=2441
@defer.inlineCallbacks 期望装饰函数是一个生成器函数并且在装饰函数内调用生成器函数(甚至返回一个)不会生成函数,生成器函数。调查:
def gen():
yield 1
def func(): return gen
import dis
dis.dis(gen)
2 0 LOAD_CONST 1 (1)
3 YIELD_VALUE
4 POP_TOP
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
dis.dis(func)
1 0 LOAD_GLOBAL 0 (gen)
3 RETURN_VALUE
import inspect
inspect.isgeneratorfunction(gen)
True
inspect.isgeneratorfunction(func)
False
所以满足 @defer.inlineCallbacks 的唯一方法是 yield 从 self.signals.send_catch_log_deferred(signal= signals.engine_started) 或来自其他地方。