在Python 3.5中,我做了一个非常简单的dict
子类,它使用同义键(存储为字典属性):
class synonymDict(dict):
def __init__(self, synonyms=None, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
self.synonyms = {} if synonyms is None else synonyms
def __getitem__(self, name):
return dict.__getitem__(self, self.synonyms.get(name, name))
def __setitem__(self, name, value):
dict.__setitem__(self, self.synonyms.get(name, name), value)
def __repr__(self):
return 'synonymDict(%s)' % dict.__repr__(self)
现在,想象一下我在myPackage.myTools
中定义了这个类;
我尝试了酸洗和酸洗(用于多处理),但是出现以下属性错误:
>>> from myPackage import myTools
>>> synonyms = dict(A='a', B='b')
>>> mymapped = myTools.synonymDict(synonyms)
>>> mymapped['A'] = 36
>>> mymapped
synonymDict({'a': 36})
>>> mymapped.synonyms
{'A': 'a', 'B': 'b'}
>>> import pickle
>>> pickle.loads(pickle.dumps(mymapped))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/users/ldog/glouvel/install/python3/LibsDyogen/myPhylTree.py", line 35, in __setitem__
dict.__setitem__(self, self.synonyms.get(name, name), value)
AttributeError: 'synonymDict' object has no attribute 'synonyms'
为什么在去渍过程中出现此错误?我应该复制synonyms
的副本吗?是子类问题还是名称空间问题?
答案 0 :(得分:0)
根据此答案https://stackoverflow.com/a/46560454/4614641,我可以用一行代码解决问题:定义默认的synonyms
class 属性。
新代码:
class synonymDict(dict):
synonyms = {} # Needed for unpickling!
def __init__(self, synonyms=None, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
self.synonyms = {} if synonyms is None else synonyms
def __getitem__(self, name):
return dict.__getitem__(self, self.synonyms.get(name, name))
def __setitem__(self, name, value):
dict.__setitem__(self, self.synonyms.get(name, name), value)
def __repr__(self):
return 'synonymDict(%s)' % dict.__repr__(self)
这是因为解开(请参见https://docs.python.org/3.5/library/pickle.html#pickling-class-instances)不会调用该类的__init__
方法,而是会尝试先调用__setitem__
!我已经重写了该方法,以调用仅在__init__
...