Python 2.7 Python-将修改后的回调传递给dispatcher

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_

应用程序,但问题实际上是关于Python语言的——专家可能会在根本不了解框架的情况下立即回答这个问题

我有一个叫做
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()