在泡菜机中,还原的确切用法是什么

2024-04-20 02:58:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道,为了可拾取,类必须覆盖__reduce__方法,并且必须返回字符串或元组

这个函数是如何工作的? __reduce__的确切用法是什么?什么时候使用


Tags: 方法函数字符串reduce用法元组
1条回答
网友
1楼 · 发布于 2024-04-20 02:58:24

当您尝试pickle对象时,可能有一些属性序列化不好。其中一个例子是打开的文件句柄。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

但是,如果我们在Test类中定义了__reduce__方法,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__方法需要返回至少包含两个元素的元组:

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

有关__reduce__方法还可以返回哪些内容的详细说明,请参阅docs

相关问题 更多 >