在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)
而不是收益?
答案 0 :(得分:5)
为什么不直接使用
self.signals.send_catch_log_deferred(signal=signals.engine_started)
而不是收益?
因为send_catch_log_deferred
会返回Deferred
个对象。如果您想避免使用yield
,那么您应该使用send_catch_log
,但使用send_catch_log_deferred
的目的是允许侦听器返回Deferred
个对象。
使用send_catch_log
的信号无法返回Deferred
个对象,因此它们不允许执行异步操作。
编辑:有关inlineCallbacks
的详细介绍,请参阅:http://krondo.com/?p=2441
答案 1 :(得分:3)
@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)或来自其他地方。< / p>