简体   繁体   English

Python pickle实例变量

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM