怎么自己腌制?

发布于 2024-08-30 08:53:20 字数 155 浏览 4 评论 0原文

我希望我的类实现 Save 和 Load 函数,这些函数只需对类进行 pickle 即可。但显然你不能以下面的方式使用“self”。你怎么能这样做呢?

self = cPickle.load(f)

cPickle.dump(self,f,2)

I want my class to implement Save and Load functions which simply do a pickle of the class. But apparently you cannot use 'self' in the fashion below. How can you do this?

self = cPickle.load(f)

cPickle.dump(self,f,2)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

归属感 2024-09-06 08:53:20

这就是我最终所做的。更新 __dict__ 意味着我们保留添加到类中的所有新成员变量,并且只更新对象上次 pickle 时存在的成员变量。这似乎是最简单的,同时在类本身内部维护保存和加载代码,因此调用代码只执行 object.save() 。

def load(self):
    f = open(self.filename, 'rb')
    tmp_dict = cPickle.load(f)
    f.close()          

    self.__dict__.update(tmp_dict) 


def save(self):
    f = open(self.filename, 'wb')
    cPickle.dump(self.__dict__, f, 2)
    f.close()

This is what I ended up doing. Updating the __dict__ means we keep any new member variables I add to the class and just update the ones that were there when the object was last pickle'd. It seems the simplest while maintaining the saving and loading code inside the class itself so calling code just does an object.save().

def load(self):
    f = open(self.filename, 'rb')
    tmp_dict = cPickle.load(f)
    f.close()          

    self.__dict__.update(tmp_dict) 


def save(self):
    f = open(self.filename, 'wb')
    cPickle.dump(self.__dict__, f, 2)
    f.close()
悲歌长辞 2024-09-06 08:53:20

转储部分应该按照您的建议工作。对于加载部分,您可以定义一个 @classmethod 从给定文件并返回它。

@classmethod
def loader(cls,f):
    return cPickle.load(f)

然后调用者会做类似的事情:

class_instance = ClassName.loader(f)

The dump part should work as you suggested. for the loading part, you can define a @classmethod that loads an instance from a given file and returns it.

@classmethod
def loader(cls,f):
    return cPickle.load(f)

then the caller would do something like:

class_instance = ClassName.loader(f)
青衫负雪 2024-09-06 08:53:20

如果你想让你的类从保存的pickle中更新自己......你几乎必须使用__dict__.update,就像你在自己的答案中一样。然而,这有点像一只猫在追它的尾巴……因为您要求实例本质上“重置”自身为之前的状态。

您的答案略有调整。您实际上可以pickle self

>>> import dill
>>> class Thing(object):
...   def save(self):
...     return dill.dumps(self)
...   def load(self, obj):
...     self.__dict__.update(dill.loads(obj).__dict__)
... 
>>> t = Thing()
>>> t.x = 1
>>> _t = t.save()
>>> t.x = 2
>>> t.x
2
>>> t.load(_t)
>>> t.x
1

我使用 loadsdumps 而不是 loaddump 因为我希望将 pickle 保存到字符串中。使用 loaddump 到文件也可以。
而且,实际上,我可以使用 dill 将类实例 pickle 到文件中,以供以后使用……即使该类是交互式定义的。从上面继续...

>>> with open('self.pik', 'w') as f:
...   dill.dump(t, f)
... 
>>> 

然后停止并重新启动...

Python 2.7.10 (default, May 25 2015, 13:16:30) 
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> with open('self.pik', 'r') as f:
...   t = dill.load(f)
... 
>>> t.x
1
>>> print dill.source.getsource(t.__class__)
class Thing(object):
  def save(self):
    return dill.dumps(self)
  def load(self, obj):
    self.__dict__.update(dill.loads(obj).__dict__)

>>> 

我正在使用 dill,可在此处使用:https://github.com/uqfoundation

If you want to have your class update itself from a saved pickle… you pretty much have to use __dict__.update, as you have in your own answer. It's kind of like a cat chasing it's tail, however… as you are asking the instance to essentially "reset" itself with prior state.

There's a slight tweak to your answer. You can actually pickle self.

>>> import dill
>>> class Thing(object):
...   def save(self):
...     return dill.dumps(self)
...   def load(self, obj):
...     self.__dict__.update(dill.loads(obj).__dict__)
... 
>>> t = Thing()
>>> t.x = 1
>>> _t = t.save()
>>> t.x = 2
>>> t.x
2
>>> t.load(_t)
>>> t.x
1

I used loads and dumps instead of load and dump because I wanted the pickle to save to a string. Using load and dump to a file also works.
And, actually, I can use dill to pickle an class instance to a file, for later use… even if the class is defined interactively. Continuing from above...

>>> with open('self.pik', 'w') as f:
...   dill.dump(t, f)
... 
>>> 

then stopping and restarting...

Python 2.7.10 (default, May 25 2015, 13:16:30) 
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> with open('self.pik', 'r') as f:
...   t = dill.load(f)
... 
>>> t.x
1
>>> print dill.source.getsource(t.__class__)
class Thing(object):
  def save(self):
    return dill.dumps(self)
  def load(self, obj):
    self.__dict__.update(dill.loads(obj).__dict__)

>>> 

I'm using dill, which is available here: https://github.com/uqfoundation

梨涡 2024-09-06 08:53:20

我就是这样做的。优点是不需要创建新对象。您可以直接加载它。

def save(self):
    with open(self.filename, 'wb') as f:
        pickle.dump(self, f)

@classmethod
def load(cls, filename):
    with open(filename, 'rb') as f:
        return pickle.load(f)

如何使用它:

class_object.save()
filename = class_object.filename
del class_object

class_object = ClassName.load(filename)

下面,我用一个完全有效的最小示例更新了答案。这可以根据您自己的需要进行调整。

import pickle

class Test:

    def __init__(self, something, filename) -> None:
        self.something = something
        self.filename = filename


    def do_something(self) -> None:
        print(id(self))
        print(self.something)

    def save(self):
        with open(self.filename, 'wb') as f:
            pickle.dump(self, f)


    @classmethod
    def load(cls, filename):
        with open(filename, 'rb') as f:
            return pickle.load(f)


test_object = Test(44, "test.pkl")
test_object.do_something()
test_object.save()
filename = test_object.filename
del test_object

recovered_object = Test.load(filename)
recovered_object.do_something()

This is how I did it. The advantage is that you do not need to create a new object. You can just load it directly.

def save(self):
    with open(self.filename, 'wb') as f:
        pickle.dump(self, f)

@classmethod
def load(cls, filename):
    with open(filename, 'rb') as f:
        return pickle.load(f)

How to use it:

class_object.save()
filename = class_object.filename
del class_object

class_object = ClassName.load(filename)

Bellow, I updated the answer with a fully working minimal example. This can be adapted to your own needs.

import pickle

class Test:

    def __init__(self, something, filename) -> None:
        self.something = something
        self.filename = filename


    def do_something(self) -> None:
        print(id(self))
        print(self.something)

    def save(self):
        with open(self.filename, 'wb') as f:
            pickle.dump(self, f)


    @classmethod
    def load(cls, filename):
        with open(filename, 'rb') as f:
            return pickle.load(f)


test_object = Test(44, "test.pkl")
test_object.do_something()
test_object.save()
filename = test_object.filename
del test_object

recovered_object = Test.load(filename)
recovered_object.do_something()
安穩 2024-09-06 08:53:20

这里的文档中有一个如何pickle实例的示例。 (向下搜索“TextReader”示例)。这个想法是定义 __getstate____setstate__ 方法,它们允许您定义需要腌制的数据,以及如何使用该数据重新实例化对象。

There is an example of how to pickle an instance here, in the docs. (Search down for the "TextReader" example). The idea is to define __getstate__ and __setstate__ methods, which allow you to define what data needs to be pickled, and how to use that data to re-instantiate the object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文