Python 2.7 Python-将修改后的回调传递给dispatcher
应用程序,但问题实际上是关于Python语言的——专家可能会在根本不了解框架的情况下立即回答这个问题 我有一个叫做Python 2.7 Python-将修改后的回调传递给dispatcher,python-2.7,callback,scrapy,Python 2.7,Callback,Scrapy,应用程序,但问题实际上是关于Python语言的——专家可能会在根本不了解框架的情况下立即回答这个问题 我有一个叫做CrawlWorker的类,它知道如何与所谓的“爬行器”对话——安排它们的爬行,并管理它们的生命周期 有一个TwistedRabbitClient,它有一个CrawlWorker。客户机只知道如何与队列对话并将消息传递给工作者-它通过使用下面的工作者方法connect\u to\u scrape连接到正在运行的爬行器发出的信号,从工作者异步获取已完成的工作: def connect_
CrawlWorker
的类,它知道如何与所谓的“爬行器”对话——安排它们的爬行,并管理它们的生命周期
有一个TwistedRabbitClient
,它有一个CrawlWorker
。客户机只知道如何与队列对话并将消息传递给工作者-它通过使用下面的工作者方法connect\u to\u scrape
连接到正在运行的爬行器发出的信号,从工作者异步获取已完成的工作:
def connect_to_scrape(self, callback):
self._connect_to_signal(callback, signals.item_scraped)
def _connect_to_signal(self, callback, signal):
if signal is signals.item_scraped:
def _callback(item, response, sender, signal, spider):
scrape_config = response.meta['scrape_config']
delivery_tag = scrape_config.delivery_tag
callback(item.to_dict(), delivery_tag)
else:
_callback = callback
dispatcher.connect(_callback, signal=signal)
因此,worker为Rabbit客户端提供了一层“工作反序列化”,它不知道爬行器、响应、发送者、信号、项目(与工作本身的性质有关的任何信息)——只知道将作为JSON发布的dict
s及其传递标记
因此,下面的回调没有正确注册(也没有错误):
但是如果我删除\u connect\u to\u signal
中的if
分支,并直接连接回调(并修改publish
以吸收所有不必要的参数),它就会工作
有人知道为什么吗?因此,我通过在更一般的上下文中重新说明,找出了这不起作用的原因:
import functools
from scrapy.signalmanager import SignalManager
SIGNAL = object()
class Sender(object):
def __init__(self):
self.signals = SignalManager(self)
def wrap_receive(self, receive):
@functools.wraps(receive)
def wrapped_receive(message, data):
message = message.replace('World', 'Victor')
value = data['key']
receive(message, value)
return wrapped_receive
def bind(self, receive):
_receive = self.wrap_receive(receive)
self.signals.connect(_receive, signal=SIGNAL,
sender=self, weak=False)
def send(self):
message = 'Hello, World!'
data = {'key': 'value'}
self.signals.send_catch_log(SIGNAL, message=message, data=data)
class Receiver(object):
def __init__(self, sender):
self.sender = sender
self.sender.bind(self.receive)
def receive(self, message, value):
"""Receive data from a Sender."""
print 'Receiver received: {0} {1}.'.format(message, value)
if __name__ == '__main__':
sender = Sender()
receiver = Receiver(sender)
sender.send()
当且仅当weak=False
时,此选项才有效
基本问题是,当连接到信号时,需要指定
weak=False
。希望比我聪明的人能解释为什么需要这样做。但是如果我删除了“连接到”信号中的if分支并直接连接回调,它就会工作。
-否则会发生什么?回调根本不会在我期望的时候被调用(就像我没有if
分支时一样),没有引发异常。回调根本没有被调用
-您是如何确认的?日志记录。回调有一些行记录到标准输出。它还发布到一个队列,该队列为空。此外,PyCharm断点不再在回调中停止。如果信号是信号。item_scraped:
-什么是信号
,什么是信号。item_scraped
?
import functools
from scrapy.signalmanager import SignalManager
SIGNAL = object()
class Sender(object):
def __init__(self):
self.signals = SignalManager(self)
def wrap_receive(self, receive):
@functools.wraps(receive)
def wrapped_receive(message, data):
message = message.replace('World', 'Victor')
value = data['key']
receive(message, value)
return wrapped_receive
def bind(self, receive):
_receive = self.wrap_receive(receive)
self.signals.connect(_receive, signal=SIGNAL,
sender=self, weak=False)
def send(self):
message = 'Hello, World!'
data = {'key': 'value'}
self.signals.send_catch_log(SIGNAL, message=message, data=data)
class Receiver(object):
def __init__(self, sender):
self.sender = sender
self.sender.bind(self.receive)
def receive(self, message, value):
"""Receive data from a Sender."""
print 'Receiver received: {0} {1}.'.format(message, value)
if __name__ == '__main__':
sender = Sender()
receiver = Receiver(sender)
sender.send()