urljoin tutorial spider example docs create python scrapy deferred

python - tutorial - ¿Qué significa @defer.inlineCallbacks cuando no necesito que yield devuelva un valor?



scrapy python 3 tutorial (2)

¿Por qué no utilizar self.signals.send_catch_log_deferred(signal=signals.engine_started) directamente sino en lugar de un rendimiento?

Porque send_catch_log_deferred devuelve un objeto Deferred . Si desea evitar un yield allí, entonces debe usar send_catch_log pero el punto de usar send_catch_log_deferred es permitir que los oyentes devuelvan objetos Deferred .

Las señales que utilizan send_catch_log no pueden devolver objetos Deferred , por lo tanto, no permiten realizar operaciones asincrónicas.

Editar: para obtener una buena introducción a inlineCallbacks consulte: http://krondo.com/?p=2441

En scrapy.core.engine

Inicio del método 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

¿Por qué no utilizar self.signals.send_catch_log_deferred(signal=signals.engine_started) directamente sino en lugar de un rendimiento?


@ defer.inlineCallbacks espera que la función decorada sea una función de generador y llamar a una función de generador dentro de la función decorada (incluso devolver una) no hace que la función, una función de generador. Una investigación:

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

Entonces, la única manera de satisfacer @defer.inlineCallbacks es o bien a diferir de self.signals.send_catch_log_deferred (signal = signals.engine_started) o desde otro lugar.