酸洗后如何更改 class 方法的定义
How can I change the definition of class methods after pickling
我正在写一个 class 来做一些数据处理。我启动了 class 并做了一些处理然后腌制了结果。
问题是我向 class 添加了新方法并加载了腌制的对象,但我无法将新方法应用于未腌制的对象。
例如,这是我的 class
class Play(ABC):
def __init__(self, data):
self.data = data
@abstractmethod
def method(self):
pass
class M(Play):
def __init__(self, data):
super().__init__(data)
def method(self):
self.corr = np.corrcoef(self.data)
我做了一些处理
mat = np.random.rand(102, 641)
s = M(mat)
s.method()
并用莳萝腌制它们
def save_object(obj, filename):
with open(filename, 'wb') as output:
dill.dump(obj, output, dill.HIGHEST_PROTOCOL)
save_object(s, 'file.pkl')
然后,我向 class 添加了新方法并解封了文件以应用这些方法,但我不能
class Play(ABC):
def __init__(self, data):
self.data = data
@abstractmethod
def method(self):
pass
class M(Play):
def __init__(self, data):
super().__init__(data)
def method(self):
self.corr = np.corrcoef(self.data)
def new(self):
# pass
self.q = self.corr.shape
def load_object(filename):
with open(filename, 'rb') as input:
obj = dill.load(input)
return obj
obj = load_object('file.pkl')
obj.new()
我得到了这个结果
AttributeError: 'M' object has no attribute 'new'
我该如何解决?
我是 dill
的作者。您可能需要查看不同的酸洗设置(请参阅 dill.settings
)。例如:
>>> class Foo(object):
... x = 1
... def bar(self, y):
... return y + self.x
...
>>> import dill
>>> f = Foo()
>>> s = dill.dumps(f)
>>> f.bar(5)
6
>>>
>>> class Foo(object):
... x = 10
... def bar(self, y):
... return y + self.x**2
...
>>> g = dill.loads(s)
>>> g.bar(5)
105
>>> g = dill.loads(s, ignore=True)
>>> g.bar(5)
6
>>> dill.settings
{'protocol': 4, 'byref': False, 'fmode': 0, 'recurse': False, 'ignore': False}
>>>
此处,ignore=True
on load 告诉 dill
如果存在更新的定义,则忽略现有的 class 定义。其他设置将用于 dump
/dumps
,例如,byref=True
告诉 dill
根本不存储 class 定义——只是使用拆箱环境中可用的任何参考资料。
您的另一种选择是使用 joblib
库。我还鼓励您查看下面 参考资料 部分中共享的 joblib
文档。
joblib.dump(obj, "filename.joblib") ## Saving object to a file
obj = joblib.load("filename.joblib") ## Loading object from a file
保存并加载您的对象:第一次
class Foo(object):
x = 1
def bar(self, y):
return y + self.x
f1 = Foo()
def checkFoo(foo: Foo):
print(f'version: {foo.version}')
## save your object
>>> version = '0.0.1'
>>> f1.version = version
>>> checkFoo(f1)
'0.0.1'
>>> joblib.dump(f1, f'object_store_v{version}.joblib')
['object_store_v0.0.1.joblib']
## load saved object (latest version)
>>> version = '0.0.1'
>>> f2 = joblib.load(f'object_store_v{version}.joblib')
>>> checkFoo(f2)
'0.0.1'
保存并加载您的对象:第二次(修改后)
## Modify object and save new version
>>> version = '0.0.2'
>>> f2.version = version
>>> checkFoo(f2)
'0.0.2'
>>> joblib.dump(f2, f'object_store_v{version}.joblib')
['object_store_v0.0.2.joblib']
## load saved object (latest version)
>>> version = '0.0.2'
>>> f3 = joblib.load(f'object_store_v{version}.joblib')
>>> checkFoo(f3)
'0.0.2'
参考资料
我正在写一个 class 来做一些数据处理。我启动了 class 并做了一些处理然后腌制了结果。 问题是我向 class 添加了新方法并加载了腌制的对象,但我无法将新方法应用于未腌制的对象。
例如,这是我的 class
class Play(ABC):
def __init__(self, data):
self.data = data
@abstractmethod
def method(self):
pass
class M(Play):
def __init__(self, data):
super().__init__(data)
def method(self):
self.corr = np.corrcoef(self.data)
我做了一些处理
mat = np.random.rand(102, 641)
s = M(mat)
s.method()
并用莳萝腌制它们
def save_object(obj, filename):
with open(filename, 'wb') as output:
dill.dump(obj, output, dill.HIGHEST_PROTOCOL)
save_object(s, 'file.pkl')
然后,我向 class 添加了新方法并解封了文件以应用这些方法,但我不能
class Play(ABC):
def __init__(self, data):
self.data = data
@abstractmethod
def method(self):
pass
class M(Play):
def __init__(self, data):
super().__init__(data)
def method(self):
self.corr = np.corrcoef(self.data)
def new(self):
# pass
self.q = self.corr.shape
def load_object(filename):
with open(filename, 'rb') as input:
obj = dill.load(input)
return obj
obj = load_object('file.pkl')
obj.new()
我得到了这个结果
AttributeError: 'M' object has no attribute 'new'
我该如何解决?
我是 dill
的作者。您可能需要查看不同的酸洗设置(请参阅 dill.settings
)。例如:
>>> class Foo(object):
... x = 1
... def bar(self, y):
... return y + self.x
...
>>> import dill
>>> f = Foo()
>>> s = dill.dumps(f)
>>> f.bar(5)
6
>>>
>>> class Foo(object):
... x = 10
... def bar(self, y):
... return y + self.x**2
...
>>> g = dill.loads(s)
>>> g.bar(5)
105
>>> g = dill.loads(s, ignore=True)
>>> g.bar(5)
6
>>> dill.settings
{'protocol': 4, 'byref': False, 'fmode': 0, 'recurse': False, 'ignore': False}
>>>
此处,ignore=True
on load 告诉 dill
如果存在更新的定义,则忽略现有的 class 定义。其他设置将用于 dump
/dumps
,例如,byref=True
告诉 dill
根本不存储 class 定义——只是使用拆箱环境中可用的任何参考资料。
您的另一种选择是使用 joblib
库。我还鼓励您查看下面 参考资料 部分中共享的 joblib
文档。
joblib.dump(obj, "filename.joblib") ## Saving object to a file
obj = joblib.load("filename.joblib") ## Loading object from a file
保存并加载您的对象:第一次
class Foo(object):
x = 1
def bar(self, y):
return y + self.x
f1 = Foo()
def checkFoo(foo: Foo):
print(f'version: {foo.version}')
## save your object
>>> version = '0.0.1'
>>> f1.version = version
>>> checkFoo(f1)
'0.0.1'
>>> joblib.dump(f1, f'object_store_v{version}.joblib')
['object_store_v0.0.1.joblib']
## load saved object (latest version)
>>> version = '0.0.1'
>>> f2 = joblib.load(f'object_store_v{version}.joblib')
>>> checkFoo(f2)
'0.0.1'
保存并加载您的对象:第二次(修改后)
## Modify object and save new version
>>> version = '0.0.2'
>>> f2.version = version
>>> checkFoo(f2)
'0.0.2'
>>> joblib.dump(f2, f'object_store_v{version}.joblib')
['object_store_v0.0.2.joblib']
## load saved object (latest version)
>>> version = '0.0.2'
>>> f3 = joblib.load(f'object_store_v{version}.joblib')
>>> checkFoo(f3)
'0.0.2'