__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.

点赞
评论