[英]Python pickle instance variables
I am doing some calculations on an instance variable, and after that is done I want to pickle the class instance, such that I don't have to do the calculations again. 我正在对一个实例变量进行一些计算,然后完成此操作,我想使该类实例腌制,这样我就不必再次进行计算。 Here an example:
这里是一个例子:
import cPickle as pickle
class Test(object):
def __init__(self, a, b):
self.a = a
self.b = b
self.c = None
def compute(self, x):
print 'calculating c...'
self.c = x * 2
test = Test(10, 'hello')
test.compute(6)
# I have computed c and I want to store it, so I don't have to recompute it again:
pickle.dump(test, open('test_file.pkl', 'wb'))
After test.compute(6)
I can check to see what test.__dict__
is: 在
test.compute(6)
我可以检查一下什么是test.__dict__
是:
>>> test.__dict__
{'a': 10, 'c': 12, 'b': 'hello'}
I thought that is what going to get pickled; 我以为那会被腌制。 however,
然而,
When I go to load the class instance: 当我去加载类实例时:
import cPickle as pickle
from pickle_class_object import Test
t2 = pickle.load(open('test_file.pkl', 'rb'))
I see this in the shell: 我在外壳中看到了这一点:
calculating c...
Which means that I did not pickle c
and I am computing it over again. 这意味着我没有腌制
c
,而是在重新计算。
Is there a way to pickle test
how I want to? 有没有一种方法来腌制
test
我怎么想? So I don't have to compute c
over again. 因此,我不必再次计算
c
。 I see that I could just pickle test.__dict__
, but I am wondering if there is a better solutions. 我看到我可以腌制
test.__dict__
,但是我想知道是否有更好的解决方案。 Also, my understanding about what is going on here is weak, so any comment about what is going would be great. 另外,我对这里发生的事情的了解很薄弱,因此任何有关正在发生的事情的评论都会很棒。 I've read about
__getstate__
and __setstate__
, but I don't see how to apply them here. 我已经读过有关
__getstate__
和__setstate__
,但是我在这里看不到如何应用它们。
You are importing the pickle_class_object
module again, and Python runs all code in that module. 您将再次导入
pickle_class_object
模块,Python将运行该模块中的所有代码。
Your top-level module code includes a call to .compute()
, that is what is being called. 您的顶级模块代码包括对
.compute()
调用。
You may want to move the code that creates the pickle out of the module, or move it to a if __name__ == '__main__':
guarded section: 您可能需要将创建泡菜的代码移出模块,或将其移至
if __name__ == '__main__':
保护的部分:
if __name__ == '__main__':
test = Test(10, 'hello')
test.compute(6)
pickle.dump(test, open('test_file.pkl', 'wb'))
Only when running a python file as the main script is __name__
set to __main__
; 仅当运行python文件作为主脚本时,
__name__
设置为__main__
; when imported as a module __name__
is set to the module name instead and the if
branch will not run. 当作为模块导入时,将
__name__
设置为模块名称,并且if
分支不会运行。
Pickling works as you expect it to work. 酸洗的工作原理与您预期的一样。 The problem here is when you run the new script, you import the module that contains the class
Test
. 这里的问题是,当您运行新脚本时,您将导入包含类
Test
的模块。 That entire module is run including the bit where you create test
. 整个模块都在运行,包括您创建
test
。
The typical way to handle this sort of thing would be to protect the stuff in a if __name__ == "__main__:
block. 处理此类问题的典型方法是在
if __name__ == "__main__:
块中保护这些内容。
class Test(object):
def __init__(self, a, b):
self.a = a
self.b = b
self.c = None
def compute(self, x):
print 'calculating c...'
self.c = x * 2
if __name__ == "__main__":
import cPickle as pickle
test = Test(10, 'hello')
test.compute(6)
# I have computed c and I want to store it, so I don't have to recompute it again:
pickle.dump(test, open('test_file.pkl', 'wb'))
That isn't what's happening. 那不是正在发生的事情。 You import a python module that has code in it at the top level, which executes when you import the module.
您导入的是其中包含代码的python模块,该模块在顶级时执行。 You can see that your code works as you intended:
您可以看到您的代码按预期工作:
import cPickle as pickle
class Test(object):
def __init__(self, a, b):
self.a = a
self.b = b
self.c = None
def compute(self, x):
print 'calculating c...'
self.c = x * 2
test = Test(10, 'hello')
test.compute(6)
pickle.dump(test, open('test_file.pkl', 'wb'))
t2 = pickle.load(open('test_file.pkl', 'rb'))
print t2.c
--output:--
calculating c...
12
If your code worked as you describe, then you would see "calculating c..." twice. 如果您的代码按您描述的那样工作,那么您将看到两次“计算c ...”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.