我知道为了可以选择,一个类必须覆盖__reduce__
方法,并且它必须返回字符串或元组。
这个功能如何运作?
__reduce__
的确切用法是什么?什么时候会被使用?
答案 0 :(得分:52)
我会看看我是否可以尝试解释这个。
每当您尝试挑选一个对象时,都会有一些可能无法顺序排列的属性。例如,一个打开的文件句柄在这种情况下,pickle将不知道如何处理该对象并将抛出错误。
您可以告诉pickle模块如何直接在类中本地处理这些类型的对象。让我们构建一个具有单个属性的对象的示例;打开文件句柄:
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)
它应该失败,并给予追溯:
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
中定义了class
方法,则pickle会知道如何序列化此对象:
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."
,它可以用来用打开的文件句柄重新创建对象:
print vars(pickle.loads(saved_object))
通常,最大的混淆是应该返回什么类型的对象__reduce__
。虽然你可以阅读更多关于什么类型的对象 reduce 应该在文档页面中返回:http://aakashlabs.org/docs/apl/pyhelp/pydocs/library/pickle.html#pickling-and-unpickling-extension-types,但一般来说,它需要一个至少2件事的元组:
self.__class__
还有其他可选项,但您应该在文档中阅读所有相关内容。
希望有所帮助!