Pickle linked objects

2019-02-09 02:44发布

I want to pickle an object and a second object that references the first. When I naively pickle/unpickle the two objects, the reference becomes a copy. How do I preserve the link between the two objects foo and bar.foo_ref?

import pickle

class Foo(object):
    pass

foo = Foo()
bar = Foo()
bar.foo_ref = foo

with open('tmp.pkl', 'wb') as f:
    pickle.dump(foo, f)
    pickle.dump(bar, f)
with open('tmp.pkl', 'rb') as f:
    foo2 = pickle.load(f)
    bar2 = pickle.load(f)

print id(foo) == id(bar.foo_ref) # True
print id(foo2) == id(bar2.foo_ref) # False
# want id(foo2) == id(bar2.foo_ref)

标签: python pickle
3条回答
闹够了就滚
2楼-- · 2019-02-09 03:17

If you pickle them together, the pickle module keeps track of references and only pickles the foo variable once. Can you pickle both foo and bar together, like this?

import pickle

class Foo(object):
    pass

foo = Foo()
bar = Foo()
bar.foo_ref = foo

with open('tmp.pkl', 'wb') as f:
    pickle.dump((foo, bar), f)
with open('tmp.pkl', 'rb') as f:
    foo2, bar2 = pickle.load(f)

print id(foo) == id(bar.foo_ref) # True
print id(foo2) == id(bar2.foo_ref) # True
查看更多
老娘就宠你
3楼-- · 2019-02-09 03:22

My previous answer was missing your point. The problem with your code is that you're not using the Pickler and Unpickler objects. Here's a working version with multiple dump calls:

import pickle

class Foo(object):
    pass

foo = Foo()
bar = Foo()
bar.foo_ref = foo

f = open('tmp.pkl', 'wb')
p = pickle.Pickler(f)
p.dump(foo)
p.dump(bar)
f.close()

f = open('tmp.pkl', 'rb')
up = pickle.Unpickler(f)
foo2 = up.load()
bar2 = up.load()

print id(foo) == id(bar.foo_ref) # True
print id(foo2) == id(bar2.foo_ref) # True
查看更多
劫难
4楼-- · 2019-02-09 03:25

Well, can you do:

bar2 = pickle.load(f)
foo2 = bar2.foo_ref

Let pickle handle the link for you.

查看更多
登录 后发表回答