我知道,为了挑选,一堂课必须覆盖 __reduce__ 方法,它必须返回字符串或元组。

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

有帮助吗?

解决方案

当您尝试腌制一个对象时,可能会有一些属性不会很好地序列化。一个例子是一个打开的文件句柄。泡菜不知道如何处理对象并会丢失错误。

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

import pickle

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

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

它应该失败并给予追溯:

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

但是,如果我们定义了 __reduce__ 我们的方法 Test 班级,泡菜会知道如何序列化此对象:

import pickle

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

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

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

print(vars(pickle.loads(saved_object)))

通常, __reduce__ 方法需要返回至少两个元素的元组:

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

咨询 文档 详细说明还有什么 __reduce__ 方法可以返回。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top