如何腌制派生的 numpy ndarray class?
How to pickle numpy ndarray derived class?
我腌制了派生自 ndarray 的 class 实例,但在 pickling/unpickling 期间丢失了属性。下面是用于说明问题的简化代码。我不明白:
- 为什么 "attrib" 不包含在 pickle dump/load 中?我必须做什么才能包含在内?
- 为什么在转储期间不调用 __getstate__() 以便我可以添加缺少的 "atrrib"? __setstate__() 被调用。状态是如何设置的?我的想法是,我会将 "attrib" 添加到获得的状态,以便稍后设置它。
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'
我完全不知道你为什么实施 __getstate__
。
尝试删除 __getstate__
然后它应该完成。
pickle 中没有 self.attrib
,因为您实现了自己的 __getstate__
和 return 只是继承自 class 的 __getstate__
。
用莳萝代替泡菜https://pypi.org/project/dill/。由于 dill 从 pickle 扩展而来,界面几乎是相同的。
import dill
with open(fname, "wb") as fh:
dill.dump(x,fh)
print("---------------")
with open(fname, "rb") as fh:
y = dill.load(fh)
Numpy 数组不实现 __getstate__ 但 __reduce__ .
见https://docs.python.org/2/library/pickle.html#pickling-and-unpickling-extension-types
__getstate__
仅当您的对象使用默认值 __reduce__
/__reduce_ex__
时才会调用。 numpy.ndarray
有自己的 __reduce__
实现,不会调用您的 __getstate__
.
numpy.ndarray.__reduce__
只包含它知道的对象数据,而不是 self.attrib
,并且 numpy.ndarray.__setstate__
不知道如何设置 self.attrib
即使你以某种方式包含该属性.
您需要实现自己的 __reduce__
和 __setstate__
并自行处理 self.attrib
。
我腌制了派生自 ndarray 的 class 实例,但在 pickling/unpickling 期间丢失了属性。下面是用于说明问题的简化代码。我不明白:
- 为什么 "attrib" 不包含在 pickle dump/load 中?我必须做什么才能包含在内?
- 为什么在转储期间不调用 __getstate__() 以便我可以添加缺少的 "atrrib"? __setstate__() 被调用。状态是如何设置的?我的想法是,我会将 "attrib" 添加到获得的状态,以便稍后设置它。
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'
我完全不知道你为什么实施 __getstate__
。
尝试删除 __getstate__
然后它应该完成。
pickle 中没有 self.attrib
,因为您实现了自己的 __getstate__
和 return 只是继承自 class 的 __getstate__
。
用莳萝代替泡菜https://pypi.org/project/dill/。由于 dill 从 pickle 扩展而来,界面几乎是相同的。
import dill
with open(fname, "wb") as fh:
dill.dump(x,fh)
print("---------------")
with open(fname, "rb") as fh:
y = dill.load(fh)
Numpy 数组不实现 __getstate__ 但 __reduce__ .
见https://docs.python.org/2/library/pickle.html#pickling-and-unpickling-extension-types
__getstate__
仅当您的对象使用默认值 __reduce__
/__reduce_ex__
时才会调用。 numpy.ndarray
有自己的 __reduce__
实现,不会调用您的 __getstate__
.
numpy.ndarray.__reduce__
只包含它知道的对象数据,而不是 self.attrib
,并且 numpy.ndarray.__setstate__
不知道如何设置 self.attrib
即使你以某种方式包含该属性.
您需要实现自己的 __reduce__
和 __setstate__
并自行处理 self.attrib
。