泡菜链接对象

时间:2011-06-16 17:31:10

标签: python pickle

我想挑选一个对象和第二个引用第一个对象的对象。当我天真地挑选/取消两个对象时,引用就变成了副本。如何保留两个对象foobar.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)

3 个答案:

答案 0 :(得分:7)

我之前的回答是错过了你的观点。您的代码存在的问题是您没有使用PicklerUnpickler个对象。这是一个包含多个转储调用的工作版本:

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

答案 1 :(得分:1)

如果你将它们一起腌制,那么pickle模块会跟踪引用,并且仅对foo变量进行一次腌制。你可以像这样一起挑选foobar吗?

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

答案 2 :(得分:0)

嗯,你能做到:

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

让pickle为你处理链接。