Alternatives to pickle's `persistent_id`? Alternatives to pickle's `persistent_id`? json json

Alternatives to pickle's `persistent_id`?


I haven't tried this yet myself, but I think you should be able to do this elegantly with PyYAML using what they call "representers" and "resolvers".

EDIT

After an extensive exchange of comments with the poster, here is a method to achieve the required behavior with PyYAML.

Important Note: If a Persistable instance has another such instance as an attribute, or contained somehow inside one of its attributes, then the contained Persistable instance will not be saved to yet another separate file, rather it will be saved inline in the same file as the parent Persistable instance. To the best of my understanding, this limitation also existed in the OP's pickle-based system, and may be acceptable for his/her use cases. I haven't found an elegant solution for this which doesn't involve hacking yaml.representer.BaseRepresenter.

import yamlfrom functools import partialclass Persistable(object):    # simulate a unique id    _unique = 0    def __init__(self, *args, **kw):        Persistable._unique += 1        self.persistent_id = ("%s.%d" %                              (self.__class__.__name__, Persistable._unique))def persistable_representer(dumper, data):    id = data.persistent_id    print "Writing to file: %s" % id    outfile = open(id, 'w')    outfile.write(yaml.dump(data))    outfile.close()    return dumper.represent_scalar(u'!xref', u'%s' % id)class PersistingDumper(yaml.Dumper):    passPersistingDumper.add_representer(Persistable, persistable_representer)my_yaml_dump = partial(yaml.dump, Dumper=PersistingDumper)def persistable_constructor(loader, node):    xref = loader.construct_scalar(node)    print "Reading from file: %s" % id    infile = open(xref, 'r')    value = yaml.load(infile.read())    infile.close()    return valueyaml.add_constructor(u'!xref', persistable_constructor)# example use, also serves as a testclass Foo(Persistable):    def __init__(self):        self.one = 1        Persistable.__init__(self)class Bar(Persistable):    def __init__(self, foo):        self.foo = foo        Persistable.__init__(self)foo = Foo()bar = Bar(foo)print "=== foo ==="dumped_foo = my_yaml_dump(foo)print dumped_fooprint yaml.load(dumped_foo)print yaml.load(dumped_foo).oneprint "=== bar ==="dumped_bar = my_yaml_dump(bar)print dumped_barprint yaml.load(dumped_bar)print yaml.load(dumped_bar).fooprint yaml.load(dumped_bar).foo.onebaz = Bar(Persistable())print "=== baz ==="dumped_baz = my_yaml_dump(baz)print dumped_bazprint yaml.load(dumped_baz)

From now on use my_yaml_dump instead of yaml.dump when you want to save instances of the Persistable class to separate files. But don't use it inside persistable_representer and persistable_constructor! No special loading function is necessary, just use yaml.load.

Phew, that took some work... I hope this helps!