为什么pickle.dumps会调用__getattr__? [英] Why does pickle.dumps call __getattr__?

查看:63
本文介绍了为什么pickle.dumps会调用__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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆