簡體   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