2

我已经玩了一些代码,显然失败的原因是当设置值时,只要我不尝试腌制和解开它'wham',该类的另一个实例就可以正常工作。 因为如果我这样做是失踪。TestDict
self.test

追溯:

Traceback (most recent call last):
  File "test.py", line 30, in <module>
    loads_a = loads(dumps_a)
  File "test.py", line 15, in __setitem__
    if self.test == False:
AttributeError: 'TestDict' object has no attribute 'test'

编码:

from pickle import dumps, loads

class TestDict(dict):
    def __init__(self, test=False, data={}):
        super().__init__(data)
        self.test = test

    def __getitem__(self, k):
        if self.test == False:
            pass
        return dict.__getitem__(self, k)

    def __setitem__(self, k, v):
        if self.test == False:
            pass
        if type(v) == dict:
            super().__setitem__(k, TestDict(False, v))
        else:
            super().__setitem__(k, v)

if __name__ == '__main__':
    a = TestDict()
    a['wham'] = {'bam' : 1}
    b = TestDict(True)
    b['wham'] = {'bam' : 2}
    dumps_a = dumps(a)
    dumps_b = dumps(b)

    loads_a = loads(dumps_a)
    loads_b = loads(dumps_b)

    print(loads_a)
    print(loads_b)

如果不替换__setitem__,代码可以工作,__getitem__但我想为这两个特定功能添加额外的功能。

我也试过:

class TestDict(dict):
    __module__ = os.path.splitext(os.path.basename(__file__))[0]

哪种有效,只要我不嵌套TestDictTestDict含义内,我就不会替换__setitem____getitem__字典的子部分。

4

2 回答 2

3

定义__reduce__方法:

class TestDict(dict):
    ...

    def __reduce__(self):
        return type(self), (self.test, dict(self))
于 2013-08-28T11:03:50.180 回答
1

问题是它在进行 unpicling 时pickle不调用对象的方法,因此在尝试设置字典的项目时不会创建变量。__init__self.test

显然设置属性是在设置字典项目之后进行的。

解决它的一种方法是添加将在实例中覆盖的类级别属性:

class TestDict(dict):
    test = False
    ...
于 2013-08-28T10:32:18.210 回答