繁体   English   中英

为什么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以避免这种情况?

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

object.__getstate__()

类可以进一步影响其实例的腌制方式。 如果该类定义了方法__getstate__() ,则会调用该方法,并将返回状态作为实例的内容(而不是实例的字典的内容)进行腌制。 如果没有__getstate__()方法,则对实例的__dict__进行腌制。

注意

在解开时间,可能会在实例上调用__getattr__()__getattribute__() __setattr__()__setattr__()之类的方法。 如果这些方法依赖于某个内部不变式为真,则该类型应实现__getinitargs__()__getnewargs__()来建立这样的不变式; 否则,将不会__new__()__init__()

由于您试图断言hasattr(self, '_data') __getinitargs__() hasattr(self, '_data')为True,因此我相信您需要使用__getinitargs__()__getnewargs__() 这是因为使用泡菜时,不会调用__init__类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM