__setstate_ 및 __getstate_의 간단한 사용 예
무슨 일인지 모르겠어요__setstate__
그리고.__getstate__
방법은 그러하므로 간단한 예를 들어 주십시오.
여기 피클 문서를 보완해야 하는 파이썬의 매우 간단한 예가 있습니다.
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)
출력:
I'm being pickled
I'm being unpickled with these values: {'val': 4}
최소 예제
결과가 어떻든getstate
에 들어갑니다.setstate
받아쓰기일 필요는 없습니다.
결과가 어떻든getstate
선택 가능해야 합니다. 예를 들어 다음과 같은 기본 내장형으로 구성됩니다.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
import pickle
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 __getstate__(self):
return { slot: getattr(self, slot) for slot in self.__slots__ }
def __setstate__(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 __getstate__(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 업스트림에서 테스트되었습니다.
이러한 방법은 피클 모듈에 의해 객체가 피클되고 제거되는 방식을 제어하는 데 사용됩니다.일반적으로 이 작업은 자동으로 처리되므로 클래스를 절이거나 절이지 않은 방법을 재정의할 필요가 없는 한 걱정할 필요가 없습니다.
@BrainCore의 답변에 대한 설명.실제로 당신은 아마도 수정하고 싶지 않을 것입니다.self
안에서.__getstate__
대신 새로운 개체를 구성하여 더 이상 사용할 수 있도록 원본을 변경하지 않습니다.다음은 이와 같은 내용입니다.
import pickle
class Foo:
def __init__(self, x:int=2, y:int=3):
self.x = x
self.y = y
self.z = x*y
def __getstate__(self):
# Create a copy of __dict__ to modify values and return;
# you could also construct a new dict (or other object) manually
out = self.__dict__.copy()
out["x"] *= 3
out["y"] *= 10
# You can remove attributes, but note they will not get set with
# some default value in __setstate__ automatically; you would need
# to write a custom __setstate__ method yourself; this might be
# useful if you have unpicklable objects that need removing, or perhaps
# an external resource that can be reloaded in __setstate__ instead of
# pickling inside the stream
del out["z"]
return out
# The default __setstate__ will update Foo's __dict__;
# so no need for a custom implementation here if __getstate__ returns a dict;
# Be aware that __init__ is not called by default; Foo.__new__ gets called,
# and the empty object is modified by __setstate__
f = Foo()
f_str = pickle.dumps(f)
f2 = pickle.loads(f_str)
print("Pre-pickle:", f.x, f.y, hasattr(f,"z"))
print("Post-pickle:", f2.x, f2.y, hasattr(f2,"z"))
언급URL : https://stackoverflow.com/questions/1939058/simple-example-of-use-of-setstate-and-getstate
'source' 카테고리의 다른 글
addClass - 동일한 div에 여러 클래스를 추가할 수 있습니까? (0) | 2023.08.12 |
---|---|
C#을 사용하여 데이터베이스에 데이터를 삽입할 때 오류 발생 (0) | 2023.08.12 |
jQuery를 사용하여 DIV에서 높이 스타일을 제거하려면 어떻게 해야 합니까? (0) | 2023.08.12 |
HTML에서 공백 없이 긴 줄을 감싸는 방법은 무엇입니까? (0) | 2023.08.12 |
jquery를 사용하여 요소 유형을 변경하는 방법 (0) | 2023.08.12 |