[英]Python 3.6: Why does pickle.dumps(nparray) permanently increase refcount?
[英]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.