在Pickler中__reduce__的确切用法是什么 [英] What's the exact usage of __reduce__ in Pickler

查看:90
本文介绍了在Pickler中__reduce__的确切用法是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,要想实现可拾取性,一个类必须覆盖__reduce__方法,并且它必须返回字符串或元组.

I know that in order to be picklable, a class has to overwrite __reduce__ method, and it has to return string or tuple.

此功能如何工作? __reduce__的确切用法是什么?什么时候使用?

How does this function work? What the exact usage of __reduce__? When will it been used?

推荐答案

我将看看我是否可以一口气解释这个问题.

I'll see if I can take a stab at explaining this one.

每当您尝试对一个对象进行腌制时,都会有些属性可能无法很好地序列化.例如,打开的文件句柄在这种情况下,泡菜将不知道如何处理该对象,并且会引发错误.

Whenever you try to pickle an object, there will be some properties that may not serialize well. For instance, an open file handle In this cases, pickle won't know how to handle the object and will throw an error.

您可以告诉pickle模块如何直接在类中本地处理这些类型的对象.让我们构建一个具有单个属性的对象的示例;一个打开的文件句柄:

You can tell the pickle module how to handle these types of objects natively within a class directly. Lets build the example of an object which has a single property; an open file handle:

import pickle

class test(object):
    def __init__(self, file_path = 'test1234567890.txt'):
        self.some_file_i_have_opened = open(file_path, 'wb')  # An open file in write mode.

my_test = test()
# Now, watch what happens when we try to pickle this object:
pickle.dumps(my_test)

它应该失败,并进行回溯:

It should fail, and give a traceback:

Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  --- snip snip a lot of lines ---
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle file objects

但是,如果我们在test class中定义了__reduce__方法,则pickle将会知道如何序列化该对象:

However, had we defined a __reduce__ method in our test class, pickle would have known how to serialize this object:

import pickle

class test(object):
    def __init__(self, file_path = 'test1234567890.txt'):
        self._file_name_we_opened = file_path  # Used later in __reduce__
        self.some_file_i_have_opened = open(self._file_name_we_opened, 'wb')  # An open file in write mode.
    def __reduce__(self):
        return (self.__class__, (self._file_name_we_opened, ))  # we return a tuple of class_name to call, and optional parameters to pass when re-creating

my_test = test()
saved_object = pickle.dumps(my_test)
print repr(saved_object)  # Just print the representation of the string of the object, because it contains newlines.

这应该给您类似的内容:"c__main__\ntest\np0\n(S'test1234567890.txt'\np1\ntp2\nRp3\n.",可用于使用打开的文件句柄重新创建对象:

This should give you something like: "c__main__\ntest\np0\n(S'test1234567890.txt'\np1\ntp2\nRp3\n.", which can be used to recreate the object with open file handles:

print vars(pickle.loads(saved_object))

通常,最大的困惑是应该返回哪种类型的对象__reduce__.同时您可以在文档页面中了解有关应返回哪种类型的对象 reduce 的更多信息:

Usually, the big confusion is with what type of object __reduce__ should return. while you can read a little more about what type of object reduce should return in the docs pages: https://docs.python.org/3/library/pickle.html#object.reduce, but in general, it needs a tuple of at least 2 things:

  1. 要调用的空白对象类.在这种情况下,self.__class__
  2. 要传递给类构造函数的参数的元组.在这种情况下,它是一个字符串,这是打开文件的路径.

还有其他可选项目,但是您应该在文档中阅读所有相关内容.

There are other optional items, but you should read all about them in the docs.

希望有帮助!

这篇关于在Pickler中__reduce__的确切用法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆