2010-05-27 9 views
7

स्लॉट वाले वर्ग से ऑब्जेक्ट को चुनने का सही तरीका क्या है, जब यह ऑब्जेक्ट अपने गुणों में से किसी एक के माध्यम से संदर्भित करता है? यहाँ एक सरल उदाहरण है, मेरे वर्तमान कार्यान्वयन है, जो मुझे यकीन है कि 100% सही है नहीं कर रहा हूँ के साथ:आत्म-संदर्भों और स्लॉट वाले वर्ग से ऑब्जेक्ट्स को अचार और अनप्लिक कैसे करें?

import weakref 
import pickle 

class my_class(object): 

    __slots__ = ('an_int', 'ref_to_self', '__weakref__') 

    def __init__(self): 
     self.an_int = 42 
     self.ref_to_self = weakref.WeakKeyDictionary({self: 1}) 

    # How to best write __getstate__ and __setstate__? 
    def __getstate__(self): 

     obj_slot_values = dict((k, getattr(self, k)) for k in self.__slots__) 
     # Conversion to a usual dictionary: 
     obj_slot_values['ref_to_self'] = dict(obj_slot_values['ref_to_self']) 
     # Unpicklable weakref object: 
     del obj_slot_values['__weakref__'] 
     return obj_slot_values 

    def __setstate__(self, data_dict): 
     # print data_dict 
     for (name, value) in data_dict.iteritems(): 
      setattr(self, name, value) 
     # Conversion of the dict back to a WeakKeyDictionary: 
     self.ref_to_self = weakref.WeakKeyDictionary(
      self.ref_to_self.iteritems()) 

इस के साथ उदाहरण के लिए परीक्षण किया जा सकता:

def test_pickling(obj): 
    "Pickles obj and unpickles it. Returns the unpickled object" 

    obj_pickled = pickle.dumps(obj) 
    obj_unpickled = pickle.loads(obj_pickled) 

    # Self-references should be kept: 
    print "OK?", obj_unpickled == obj_unpickled.ref_to_self.keys()[0] 
    print "OK?", isinstance(obj_unpickled.ref_to_self, 
          weakref.WeakKeyDictionary) 

    return obj_unpickled 

if __name__ == '__main__': 
    obj = my_class() 
    obj_unpickled = test_pickling(obj) 
    obj_unpickled2 = test_pickling(obj_unpickled) 

यह एक सही/मजबूत है कार्यान्वयन? और __setstate__ को __slots__ के साथ कक्षा से विरासत में कैसे लिखा जाना चाहिए? क्या "परिपत्र" के कारण __setstate__ के अंदर एक स्मृति रिसाव है?

PEP 307 में एक टिप्पणी मुझे आश्चर्य है कि क्या my_class वस्तुओं नमकीन बनाना बिल्कुल भी एक मजबूत तरह से संभव है कि बनाता है नहीं है:

__getstate__ विधि वस्तु ही संदर्भ के बिना एक picklable मूल्य वस्तु के राज्य का प्रतिनिधित्व करने लौटना चाहिए ।

क्या यह इस तथ्य से संघर्ष करता है कि वस्तु का संदर्भ स्वयं उठाया जाता है?

यह बहुत सारे प्रश्न हैं: कोई टिप्पणी, टिप्पणी या सलाह की सराहना की जाएगी!

+1

यदि आप my_class को उप-वर्गीकरण करना चाहते हैं, तो स्वयं को .__ slots__ को कुछ ऐसा करने के लिए सुनिश्चित करें: slots = set(); स्वयं में cls के लिए .__ वर्ग __। mro(): slots.update (getattr (cls, '__slots__',())) –

+1

मेरे सिर के ऊपर से, मैं कहूंगा कि उपclasses 'self .__ slots__' अपडेट करते हैं, इसलिए मुझे लगता है वास्तव में subclassing के साथ कोई समस्या नहीं होगी, है ना? – EOL

+0

नहीं। वे नहीं करते :-) यह पता लगाने में कुछ समय लगा, इसलिए टिप्पणी। :-) –

उत्तर

5

ऐसा लगता है कि मूल पोस्ट सुझाव देता है कि यह काफी अच्छा काम करता है।

पीईपी 307 क्या पढ़ता है के लिए के रूप में:

__getstate__ विधि वस्तु ही संदर्भ के बिना एक picklable मूल्य वस्तु के राज्य का प्रतिनिधित्व करने लौटना चाहिए।

मैं समझता हूं कि इसका मतलब केवल यह है कि __getstate__ विधि को केवल उस प्रतिनिधित्व को वापस करना होगा जो मूल वस्तु (अप्रचलित) मूल वस्तु को इंगित नहीं करता है। इस प्रकार, किसी ऑब्जेक्ट को वापस संदर्भित करना ठीक है, जब तक कि मूल (अप्रचलित) ऑब्जेक्ट का कोई संदर्भ नहीं बनाया जाता है।

संबंधित मुद्दे