让对象序列化自身

问题描述 投票:0回答:1

使用 JSON 或 Pickle,我可以实例化一个对象并保存该对象,如下所示:

import pickle 
thing = Thingy(some_data) # takes a while...
# ... do stuff with thing then save it since it mostly is the same
with open(filename, 'wb') as f: 
    pickle.dump(thing, f)

如果序列化文件存在则读回:

if thingy_file.exists():
    with open(filename, 'rb') as f:
        thing=pickle.load(f)  # Thingy(some_data) restored
    thing.updateyourself()  # pretty fast
else: 
    thing=Thingy(some_data) # takes a while...

但是,此序列化是在 Thingy 对象的实例化外部完成的...

现在假设我有一些带有内部数据的自定义对象,需要花费很长时间来创建:

class Thingy:
   def __init__(self, stuff...)
      # this take a while the first time, but could be instant if read back
      # pseudo'ish:
        if self.file.exists():
            print(f'Existing Thingy {self.file} found...')
            # What I am trying to do here is read from a serialization file the
            # data comprising the last time THIS INSTANCE of Thingy existed
             with open(self.file, 'rb') as f:
                self=pickle.load(f)
        else:
           # bummer this is gonna take a while...
        
        # the rest of the object code...
        # HERE we either have calculated a Thingy or have read it back into itself
        # The instance may be modified -- now save its own self to be re-read in future:
     
    def save_my_own_instance(self):
       # now self is this instance of Thingy that will be serialized to disk
       # magic I do not know...
       with open(self.file, 'wb') as f:
            pickle.dump(my_own_instance_data, f, pickle.HIGHEST_PROTOCOL)

那么问题:对象使用序列化将自己的数据恢复到自己的实例中的方法是什么?将自身保存在自己的实例中怎么样?


什么是

Thingy
的一些细节:

from pathlib import Path

p=Path(a_HUGE_tree_of_data_files) # 750k plus large image files

tree_data=Thingy(p)
# initial run on p is hour+
# the tree changes very little, so an update of Thingy(p) 
# only takes seconds

# I don't want to educate the user to check for a previous run
# It should be automatic
python json object serialization pickle
1个回答
0
投票

解决此问题的一种方法是在

Thingy
中创建一个静态方法。

class Thingy:
    @staticmethod
    def load_instance_from_file_or_create_new(filename, stuff):
        if filename.exists():# check if file exists
            with open(filename, 'rb') as f:
                instance=pickle.load(f)
            return instance
        return Thingy(stuff)

    def __init__(self, stuff):
        # create the instance normally

    def __del__(self):
        # the instance is being deleted
        with open(self.file, 'wb') as f:
            pickle.dump(my_own_instance_data, f, pickle.HIGHEST_PROTOCOL)

可以用作

thing = Thingy.load_instance_from_file_or_create_new("xyz",stuff)

静态方法从文件加载

Thingy
实例(如果文件存在),否则使用提供的
stuff
创建一个新实例。
您必须将
filename
存储在
Thingy
之外,除非您有默认的
filename

每当实例被销毁时,都会自动调用
__del__
方法,因此您可以使用它将实例存储到文件中。

© www.soinside.com 2019 - 2024. All rights reserved.