Class Sketch(dict) 重构(unpickle)错误(见下面的代码):
Failed example:
s2 = pickle.loads(b)
Exception raised:
Traceback (most recent call last):
File "/usr/lib/python3.9/doctest.py", line 1336, in __run
exec(compile(example.source, filename, "single",
File "<doctest __main__[10]>", line 1, in <module>
s2 = pickle.loads(b)
File "/home/vlz/Documents/py31eg/image/pickle_lab.py", line 66, in __setitem__
if color != self.background:
AttributeError: 'Sketch' object has no attribute 'background'
**********************************************************************
1 items had failures:
1 of 12 in __main__
***Test Failed*** 1 failures.
这就是我开始的地方。他的对手 Sketch_has_dict(object) pickle/unpickle -ed 成功(在下面的同一测试中)。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
>>> s = Sketch_has_dict()
>>> for y in range(2):
... for x in range(3):
... s[(x, y)] = 'yellow'
...
>>> import pickle
>>> b = pickle.dumps(s, protocol=pickle.HIGHEST_PROTOCOL)
>>> s2 = pickle.loads(b)
>>> len(s2)
6
>>> s = Sketch()
>>> for y in range(2):
... for x in range(3):
... s[(x, y)] = 'yellow'
...
>>> import pickle
>>> b = pickle.dumps(s, protocol=pickle.HIGHEST_PROTOCOL)
>>> s2 = pickle.loads(b)
>>> len(s2)
6
"""
class Sketch_has_dict:
def __init__(self, width=3, height=2, background='red'):
self.color = set()
self.width = width
self.height = height
self.background = background
self.pixels = {}
def __len__(self):
return len(self.pixels)
def __getitem__(self, coord):
return self.pixels.get(coord, self.background)
def __setitem__(self, coord, color):
if color != self.background:
self.pixels[coord] = color
def __repr__(self):
return repr(self.pixels)
class Sketch(dict):
def __new__(cls):
s = super().__new__(cls)
s.colors = set()
s.width = 3
s.height = 2
s.background = 'red'
return s
def __init__(self, width=3, height=2, background='red'):
self.colors = set()
self.width = width
self.background = background
self.height = height
super(Sketch, self).__init__()
def __setitem__(self, coord, color=None):
if color != self.background:
self.colors.add(color)
super(Sketch, self).__setitem__(coord, color)
if __name__ == '__main__':
import doctest
doctest.testmod()
当我将 __new__ 方法添加到 Sketch(dict) 类时,测试通过了。我硬编码了初始 attr 值。我不清楚在重构对象时何时以及使用什么参数调用 __new__ 。
当我需要 pickle-able 类时,我应该实现什么神奇的方法?看起来 __init__ 在重构(pickle.loads)两个实例时没有被调用。重构对象时 pickle.loads() 的步骤是什么?
使用 Python 3.9.2,Debian GNU/Linux 11(靶心)
附言 我重读了我的问题。听起来不清楚。换句话说:我应该如何重构我的 Sketch 类以使其适合 pickle.dumps、pickle.loads?