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.