gpt4 book ai didi

python - 为什么 pickle.dumps 会调用 __getattr__?

转载 作者:太空宇宙 更新时间:2023-11-03 11:33:29 24 4
gpt4 key购买 nike

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 来避免这种情况?

最佳答案

根据 cPickle 的文档:http://docs.python.org/library/pickle.html

object.__getstate__()

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.

Note

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') 为真,我相信您需要使用 __getinitargs__()__getnewargs__ ()。这是因为在使用 pickle 时,没有调用类的 __init__ 方法。

关于python - 为什么 pickle.dumps 会调用 __getattr__?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12101574/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com