__setstate__
및 __getstate__
메소드가 무엇을하는지 모르겠습니다 . 간단한 예를 들어 도와주세요.
답변
다음은 pickle 문서를 보완해야하는 매우 간단한 Python 예제입니다 .
class Foo(object):
def __init__(self, val=2):
self.val = val
def __getstate__(self):
print("I'm being pickled")
self.val *= 2
return self.__dict__
def __setstate__(self, d):
print("I'm being unpickled with these values: " + repr(d))
self.__dict__ = d
self.val *= 3
import pickle
f = Foo()
f_data = pickle.dumps(f)
f_new = pickle.loads(f_data)
답변
최소한의 예
어쨌든 나오는 getstate
로 간다 setstate
. dict 일 필요는 없습니다.
무엇이든 나오는 getstate
pickeable해야합니다, 예를 들어 같은 기본 내장 된 기능들로 구성 int
, str
, list
.
class C(object):
def __init__(self, i):
self.i = i
def __getstate__(self):
return self.i
def __setstate__(self, i):
self.i = i
assert pickle.loads(pickle.dumps(C(1), -1)).i == 1
기본 __setstate__
기본값 __setstate__
은 dict
.
self.__dict__
https://stackoverflow.com/a/1939384/895245 에서 와 같이 좋은 선택 이지만 상황을 더 잘보기 위해 직접 구성 할 수 있습니다.
class C(object):
def __init__(self, i):
self.i = i
def __getstate__(self):
return {'i': self.i}
assert pickle.loads(pickle.dumps(C(1), -1)).i == 1
기본 __getstate__
과 유사 __setstate__
.
class C(object):
def __init__(self, i):
self.i = i
def __setstate__(self, d):
self.i = d['i']
assert pickle.loads(pickle.dumps(C(1), -1)).i == 1
__slots__
개체에는 없습니다 __dict__
객체가있는 경우 __slots__
, 그것은하지 않습니다__dict__
get
및을 모두 구현 setstate
하려는 경우 기본 방식은 다음과 같습니다.
class C(object):
__slots__ = 'i'
def __init__(self, i):
self.i = i
def __getsate__(self):
return { slot: getattr(self, slot) for slot in self.__slots__ }
def __setsate__(self, d):
for slot in d:
setattr(self, slot, d[slot])
assert pickle.loads(pickle.dumps(C(1), -1)).i == 1
__slots__
기본 get 및 set에는 튜플이 필요합니다.
기본을 다시 사용하려는 경우 __getstate__
또는 __setstate__
, 당신은 주위 튜플을 통과해야합니다 :
class C(object):
__slots__ = 'i'
def __init__(self, i):
self.i = i
def __getsate__(self):
return (None, { slot: getattr(self, slot) for slot in self.__slots__ })
assert pickle.loads(pickle.dumps(C(1), -1)).i == 1
이것이 무엇을위한 것인지 잘 모르겠습니다.
계승
먼저 산 세척이 기본적으로 작동하는지 확인하십시오.
class C(object):
def __init__(self, i):
self.i = i
class D(C):
def __init__(self, i, j):
super(D, self).__init__(i)
self.j = j
d = pickle.loads(pickle.dumps(D(1, 2), -1))
assert d.i == 1
assert d.j == 2
상속 사용자 정의 __getstate__
없이 __slots__
그것은 이후, 쉬운 __dict__
을위한 D
을 포함 __dict__
위해 C
우리가 접촉 할 필요가 없습니다, C
전혀 :
class C(object):
def __init__(self, i):
self.i = i
class D(C):
def __init__(self, i, j):
super(D, self).__init__(i)
self.j = j
def __getstate__(self):
return self.__dict__
def __setstate__(self, d):
self.__dict__ = d
d = pickle.loads(pickle.dumps(D(1, 2), -1))
assert d.i == 1
assert d.j == 2
상속 및 __slots__
를 사용 __slots__
하면 기본 클래스로 전달해야하며 튜플을 전달할 수 있습니다.
class C(object):
__slots__ = 'i'
def __init__(self, i):
self.i = i
def __getstate__(self):
return { slot: getattr(self, slot) for slot in C.__slots__ }
def __setstate__(self, d):
for slot in d:
setattr(self, slot, d[slot])
class D(C):
__slots__ = 'j'
def __init__(self, i, j):
super(D, self).__init__(i)
self.j = j
def __getstate__(self):
return (
C.__getstate__(self),
{ slot: getattr(self, slot) for slot in self.__slots__ }
)
def __setstate__(self, ds):
C.__setstate__(self, ds[0])
d = ds[1]
for slot in d:
setattr(self, slot, d[slot])
d = pickle.loads(pickle.dumps(D(1, 2), -1))
assert d.i == 1
assert d.j == 2
불행히도 기본값 __getstate__
과 기본을 재사용하는 것은 불가능합니다 __setstate__
: https://groups.google.com/forum/#!topic/python-ideas/QkvOwa1-pHQ 우리는 그들을 정의해야합니다.
Python 2.7.12에서 테스트되었습니다. GitHub 업스트림 .
답변
이러한 메서드는 pickle 모듈 에서 개체를 피클 및 언 피클하는 방법을 제어하는 데 사용됩니다 . 이것은 일반적으로 자동으로 처리되므로 클래스가 피클되거나 언 피클되는 방식을 재정의 할 필요가없는 한 걱정할 필요가 없습니다.