当我不需要 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) 或来自其他地方。