我想在 python 中序列化一个类实例并保持方法持久化。我尝试过 joblib 和 pickle,并且非常接近 dill,但不太明白。
问题就在这里。假设我想像这样腌制一个类实例:
import dill
class Test():
def __init__(self, value=10):
self.value = value
def foo(self):
print(f"Bar! Value is: {self.value}")
t = Test(value=20)
with open('Test.pkl', 'wb+') as fp:
dill.dump(t, fp)
# Test it
print('Original: ')
t.foo() # Prints "Bar! Value is: 20"
后来,
Test
的定义发生了变化,当我重新加载我的pickled对象时,方法是不同的:
class Test():
def __init__(self, value=10):
self.value = value
def foo(self):
print("...not bar?")
with open('Test.pkl', 'rb') as fp:
t2 = dill.load(fp)
# Test it
print('Reloaded: ')
t2.foo() # Prints "...not bar?"
现在在重新加载的情况下,属性值被保留(
t2.value
为20)。通过使用 dill 序列化类而不是实例,我可以非常接近我想要的,如下所示:
class Test():
def __init__(self, value=10):
self.value = value
def foo(self):
print(f"Bar! Value is: {self.value}")
t = Test(value=20)
with open('Test.pkl', 'wb+') as fp:
dill.dump(Test, fp)
# Test it
print('Original: ')
t.foo() # Prints "Bar! Value is: 20"
但是当我重建它时,我得到了旧方法(我想要的),但我丢失了实例的属性
t
(在这种情况下,我得到默认值10而不是实例值20):
class Test():
def __init__(self, value=10):
self.value = value
def foo(self):
print("...not bar?")
with open('Test.pkl', 'rb') as fp:
test_class = dill.load(fp)
t2 = test_class()
# Test it
print('Reloaded: ')
t2.foo() # Prints "Bar! Value is: 10"
在我的实际用例中,类实例中有很多属性。我希望能够腌制属性和方法,以便以后的源代码更改不会使该特定对象不可恢复。
目前,为了恢复这些对象,我正在复制源代码文件,但导入变得非常混乱——很多
sys.path
操作变得令人困惑,以确保我加载正确的旧源代码。我还可以做一些事情,我用 dill 腌制类定义,然后将所有属性保存到 json 或其他东西并以这种方式重建,但我想知道是否有一种简单的方法可以用 dill 或我的其他一些包来做到这一点还没有发现。对我来说这似乎是一个简单的用例。
import cloudpickle
# Initial class
class Test:
def __init__(self, value=10):
self.value = value
def foo(self):
print(f"Bar! Value is: {self.value}")
t = Test(value=20)
with open('test.pkl', 'wb') as f:
cloudpickle.dump(t, f)
# Re-definition of class
class Test:
def __init__(self, value=10):
self.value = value
def foo(self):
print("...not bar?")
# Load original instance
with open('test.pkl', 'rb') as f:
t2 = cloudpickle.load(f)
t2.foo()
# Bar! Value is: 20