我腌制了一个从ndarray派生的类的实例,但是在腌制/解腌期间丢失了属性。下面是简化的代码来说明此问题。我不明白:
import numpy as np
import pickle
class Xndarray(np.ndarray):
def __new__(cls, **kwargs):
return super().__new__(cls, (5, 3), **kwargs)
def __init__(self, **kwargs):
self[...] = -1
self.attrib = 0
def add2getstate(self):
print("add2getstate()", self.__dict__)
def __getstate__(self): # This never gets called
print("__getstate__()")
return super().__getstate__()
def __setstate__(self, data):
print("__setstate__()")
super().__setstate__(data)
if __name__ == "__main__":
fname = "fname.pkl"
x = Xndarray()
x[0] = 0
x.attrib += 2
print(x)
x.add2getstate()
print(x.attrib)
with open(fname, "wb") as fh:
pickle.dump(x, fh)
print("---------------")
with open(fname, "rb") as fh:
y = pickle.load(fh)
print(y)
y.add2getstate()
print(y.attrib)
以下是输出:
[[ 0. 0. 0.]
[-1. -1. -1.]
[-1. -1. -1.]
[-1. -1. -1.]
[-1. -1. -1.]]
add2getstate() {'attrib': 2}
2
---------------
__setstate__()
[[ 0. 0. 0.]
[-1. -1. -1.]
[-1. -1. -1.]
[-1. -1. -1.]
[-1. -1. -1.]]
add2getstate() {}
Traceback (most recent call last):
File "./t.py", line 48, in <module>
print(y.attrib)
AttributeError: 'Xndarray' object has no attribute 'attrib'
答案 0 :(得分:1)
__getstate__
如果对象使用默认仅称为__reduce__
/ __reduce_ex__
。 numpy.ndarray
有自己的__reduce__
实现不打电话给你__getstate__
numpy.ndarray.__reduce__
仅包含其知道的对象数据,而不包含self.attrib
,并且numpy.ndarray.__setstate__
不知道如何设置self.attrib
,即使您以某种方式包含了该属性。 / p>
您将需要实现自己的__reduce__
和__setstate__
和{手柄{1}}自己。
答案 1 :(得分:0)
我完全不知道您为什么实施__getstate__
。
尝试删除__getstate__
,然后它应该是完整的。
泡菜中没有self.attrib
,因为您实现了自己的__getstate__
并仅从继承的类中返回__getstate__
。
答案 2 :(得分:0)
使用莳萝代替泡菜https://pypi.org/project/dill/。作为莳萝泡菜从扩展接口几乎是一样的。
import dill
with open(fname, "wb") as fh:
dill.dump(x,fh)
print("---------------")
with open(fname, "rb") as fh:
y = dill.load(fh)
答案 3 :(得分:0)
Numpy数组不实现__getstate__,但是实现__reduce__。
请参见https://docs.python.org/2/library/pickle.html#pickling-and-unpickling-extension-types