मुझे नहीं पता कि क्या __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)
न्यूनतम उदाहरण
जो भी बाहर आता है, getstateभीतर चला जाता है setstate। इसे डिक्टेट करने की जरूरत नहीं है।
जो कुछ भी से बाहर आता है getstatepickeable होना चाहिए, जैसे बुनियादी बनाया-इन से बना जैसे 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, डिफ़ॉल्ट-ish तरीका है:
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__ डिफ़ॉल्ट मिलता है और सेट एक टपल की उम्मीद है
यदि आप डिफ़ॉल्ट का पुन: उपयोग करना चाहते हैं __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 हम उन्हें परिभाषित करने के लिए मजबूर हैं।
पायथन 2.7.12 पर परीक्षण किया गया। गिटहब ऊपर ।
इन तरीकों का उपयोग यह नियंत्रित करने के लिए किया जाता है कि अचार मॉड्यूल द्वारा वस्तुओं को कैसे उठाया और अप्रकाशित किया जाता है । यह आमतौर पर स्वचालित रूप से नियंत्रित किया जाता है, इसलिए जब तक आपको ओवरराइड करने की आवश्यकता नहीं होती है कि क्लास को कैसे उठाया जाता है या अप्रकाशित किया जाता है, तो आपको इसके बारे में चिंता करने की आवश्यकता नहीं है।