__reduce__是否接受参数?

When I read code from others, I found someone defines __reduce__ for the class accepting arguments. For instance, here. If you are not aware, __reduce__ magic method is for pickling a Python object.

    def __reduce__(self, args=(), kwargs=None):
        kwargs = {} if not kwargs else kwargs
        return (unpickle_backend, (self.__class__, args, kwargs))

So I quote the document:

The interface is currently defined as follows. The __reduce__() method takes no argument and shall return either a string or preferably a tuple (the returned object is often referred to as the “reduce value”).

有人帮我理解吗?

评论
  • 22相亲
    22相亲 回复

    The pickle machinery will only ever call __reduce__ without arguments. Celery has chosen to overload their __reduce__ implementations to support arguments; these arguments are used by Celery internally, and are not provided by the pickle machinery. Since the extra arguments are optional, these __reduce__ methods can still handle no-argument calls, and they are still compatible with the __reduce__ protocol.

    For example, celery.backends.rpc.RPCBackend.__reduce__ looks like this:

    def __reduce__(self, args=(), kwargs={}):
        return super(RPCBackend, self).__reduce__(args, dict(
            kwargs,
            connection=self._connection,
            exchange=self.exchange.name,
            exchange_type=self.exchange.type,
            persistent=self.persistent,
            serializer=self.serializer,
            auto_delete=self.auto_delete,
            expires=self.expires,
        ))
    

    It passes a non-empty kwargs argument to super().__reduce__. The delegated-to __reduce__ implementation can handle that, but it's not a call the pickle machinery would ever make directly.