我知道,为了可腌制,一个类必须覆盖__reduce__
方法,并且它必须返回字符串或元组。
这个功能是如何工作的?的具体用法是__reduce__
什么?什么时候使用?
当您尝试腌制一个对象时,可能有一些属性不能很好地序列化。其中一个示例是打开的文件句柄。Pickle 不知道如何处理该对象并会抛出错误。
您可以直接告诉 pickle 模块如何在类中本地处理这些类型的对象。让我们看一个具有单个属性的对象的示例;一个打开的文件句柄:
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
,pickle 就会知道如何序列化这个对象:
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__
方法需要返回一个至少包含两个元素的元组:
self.__class__
有关该方法可以返回的其他内容的详细说明,请参阅文档。__reduce__