当我不需要yield时,@ defer.inlineCallbacks的含义是什么?

时间:2015-03-05 05:50:24

标签: python scrapy deferred

在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)而不是收益?

2 个答案:

答案 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>