我不明白__reduce__函数如何在
Python中的pickle模块中完全有效.
假设我有以下课程:
class Foo(object):
def __init__(self, file_name = 'file.txt'):
self.file_name = file_name
self.f = open(self.file_name, 'w')
它不能被腌制,因为pickle模块不知道如何编码文件句柄:
foo = Foo()
print(pickle.dumps(foo))
输出:
TypeError: can't pickle file objects
但是,如果我添加__reduce__函数,它会成功编码:
import pickle
class Foo(object):
def __init__(self, file_name = 'file.txt'):
self.file_name = file_name
self.f = open(self.file_name, 'w')
def __reduce__(self):
return (self.__class__, (self.file_name, ))
foo = Foo()
print(pickle.dumps(foo))
输出:
c__main__
Foo
p0
(S'file.txt'
p1
tp2
Rp3
.
我是对的,如果pickle.dumps调用失败,__ reduce__函数只是为解构器返回“指令”重新创建原始对象?
从文档中我不清楚.
最佳答案 你是对的. __reduce__方法应该返回提示如何重建(unpickle)对象,以防它无法自动腌制.它可能包含一个对象引用和参数,通过它可以调用它来创建对象的初始版本,对象的状态等.
If a string is returned, the string should be interpreted as the name of a global variable. It should be the object’s local name relative to its module; the pickle module searches the module namespace to determine the object’s module. This behaviour is typically useful for singletons.
When a tuple is returned, it must be between two and five items long. Optional items can either be omitted, or None can be provided as their value. The semantics of each item are in order:
- A callable object that will be called to create the initial version of the object.
- A tuple of arguments for the callable object. An empty tuple must be given if the callable does not accept any argument.
- Optionally, the object’s state, which will be passed to the object’s
__setstate__()
method as previously described. If the object has no such method then, the value must be a dictionary and it will be added to the object’s__dict__
attribute.- Optionally, an iterator (and not a sequence) yielding successive items. These items will be appended to the object either using
obj.append(item)
or, in batch, usingobj.extend(list_of_items)
. This is primarily used for list subclasses, but may be used by other classes as long as they haveappend()
andextend()
methods with the appropriate signature. (Whetherappend()
orextend()
is used depends on which pickle protocol version is used as well as the number of items to append, so both must be supported.)- Optionally, an iterator (not a sequence) yielding successive key-value pairs. These items will be stored to the object using
obj[key] = value
. This is primarily used for dictionary subclasses, but may be used by other classes as long as they implement__setitem__()
.