【问题标题】:What does @defer.inlineCallbacks mean when I don't need yield return a value?当我不需要 yield 返回值时,@defer.inlineCallbacks 是什么意思?
【发布时间】:2015-03-05 05:50:24
【问题描述】:

在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?

【问题讨论】:

标签: python scrapy deferred


【解决方案1】:

为什么不直接使用self.signals.send_catch_log_deferred(signal=signals.engine_started),而是使用yield?

因为send_catch_log_deferred 返回一个Deferred 对象。如果你想避免在那里出现yield,那么你应该使用send_catch_log,但使用send_catch_log_deferred的目的是让听众返回Deferred对象。

使用send_catch_log 的信号无法返回Deferred 对象,因此它们不允许执行异步操作。

编辑:有关inlineCallbacks 的详细介绍,请参阅:http://krondo.com/?p=2441

【讨论】:

    【解决方案2】:

    @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) 或从其他地方延迟。

    【讨论】:

      猜你喜欢
      • 2013-04-25
      • 2021-01-24
      • 1970-01-01
      • 2014-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-13
      相关资源
      最近更新 更多