为什么pickle.dumps会调用__getattr__? [英] Why does pickle.dumps call __getattr__?
问题描述
import cPickle
class Foo(object):
def __init__(self):
self._data = {'bar': 'baz'}
def __getattr__(self, name):
assert hasattr(self, '_data')
return self._data[name]
# I even had to define this just to stop KeyError: '__getstate__'
def __getstate__(self):
return self.__dict__
foo = Foo()
bar = cPickle.dumps(foo)
cPickle.loads(bar)
这会引发断言错误.
我认为pickle
/cPickle
只是在转储时将__dict__
转换为字符串,然后在加载时使用该字符串直接设置新对象的__dict__
.为什么dumps
需要调用bar.__getattr__
?如何更改Foo
以避免这种情况?
I thought pickle
/cPickle
just turns __dict__
into a string when dumping and then uses that string to set the __dict__
of the new object directly when loading. Why would dumps
need to call bar.__getattr__
? How can I change Foo
to avoid that?
推荐答案
根据cPickle的文档: http://docs.python.org/library/pickle.html
According the documentation for cPickle: http://docs.python.org/library/pickle.html
object.__getstate__()
类可以进一步影响其实例的腌制方式;如果该类定义了方法
__getstate__()
,则会调用该方法,并将返回状态作为实例的内容而不是实例字典的内容进行腌制.如果没有__getstate__()
方法,则对实例的__dict__
进行腌制.
Classes can further influence how their instances are pickled; if the class defines the method
__getstate__()
, it is called and the return state is pickled as the contents for the instance, instead of the contents of the instance’s dictionary. If there is no__getstate__()
method, the instance’s__dict__
is pickled.
注意
在提货时,某些方法,例如__getattr__()
,
可以在实例上调用__getattribute__()
或__setattr__()
.如果这些方法依赖于某些内部不变性为真,则
类型应实现__getinitargs__()
或__getnewargs__()
建立这样一个不变式;否则,__new__()
或
__init__()
将被调用.
At unpickling time, some methods like __getattr__()
,
__getattribute__()
, or __setattr__()
may be called upon the instance. In case those methods rely on some internal invariant being true, the
type should implement either __getinitargs__()
or __getnewargs__()
to
establish such an invariant; otherwise, neither __new__()
nor
__init__()
will be called.
由于您试图断言hasattr(self, '_data')
为True,因此我相信您需要使用__getinitargs__()
或__getnewargs__()
.这是因为使用泡菜时,不会调用类__init__
的方法.
Since you are trying to assert that hasattr(self, '_data')
is True, I believe that you need to use __getinitargs__()
or __getnewargs__()
. This is because when using pickle, a classes __init__
method is not called.
这篇关于为什么pickle.dumps会调用__getattr__?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!