考虑以下 MWE:
#import dill as pickle # Dill exhibits similar behavior
import pickle
class B:
def __init__(self):
self.links = set()
class A:
def __init__(self, base: B):
self.base = base
base.links.add(self)
def __hash__(self):
return hash(self.base)
def __eq__(self, other):
return self.base == other.base
pickled = pickle.dumps(A(B())) # Success
print(pickle.loads(pickled)) # Not so much
上面的示例失败,但出现以下异常:
Traceback (most recent call last):
File "./mwe.py", line 26, in <module>
print(pickle.loads(pickled))
File "./mwe.py", line 18, in __hash__
return hash(self.base)
AttributeError: 'A' object has no attribute 'base'
B.links
据我了解这个问题,pickle 在反序列化之前尝试反序列化A
。set
用于B
尝试在某个点调用的A.__hash__
实例,并且由于实例A
尚未完全构造,它无法计算自己的哈希,这让每个人都感到难过。
如何在不破坏循环引用的情况下解决这个问题?(打破循环将是很多工作,因为我试图序列化的对象非常复杂)