2010-05-27 14 views
7

Nesnenin kendi özelliklerinden biri aracılığıyla başvurduğu zaman, bir nesneyi yuvalardan oluşan bir sınıftan seçmenin doğru yolu nedir?Nesneleri kendi kendine referanslar ve yuvaları olan bir sınıftan nasıl seçip kaldırabilirsiniz?

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()) 

Bu birlikte örneğin test edilebilir:

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) 

bu doğru/sağlam mı Burada basit bir örnek Doğru% 100 emin değilim benim şimdiki uygulanması ile, bir uygulama? my_class__slots__ ile bir sınıftan miras alınmışsa __getstate__ ve __setstate__ nasıl yazılmalıdır? "dairesel" dict nedeniyle __setstate__ içinde bir bellek sızıntısı var mı?

__getstate__ yöntem nesnenin kendisini bakmadan nesnenin durumunu temsil eden bir picklable değerini döndürmesi gerekir: me my_class nesneleri dekapaj mümkünse sağlam bir şekilde olup olmadığını merak ediyor PEP 307 bir açıklama yoktur

.

Bu, nesnenin kendisinin bir referansının alınmasıyla çakışıyor mu?

Bu bir çok soru: herhangi bir yorum, yorum veya tavsiye çok takdir edilecektir!

+1

Eğer my_class'ın alt sınıflara ayrılmasını istiyorsanız, self .__ slots__ 'yu aşağıdaki gibi değiştirmeyi unutmayın: slots = set(); self .__ class __. mro() 'da cls için: slots.update (getattr (cls,' __slots__ ',())) –

+1

Başımın üst kısmından, alt sınıfların 'self .__ slots__' güncellendiğini söyleyebilirim. Alt sınıfla ilgili bir problem olmayacak, değil mi? – EOL

+0

Hayır. Yapmıyorlar. :-) Bu dışarıda biraz zaman aldı, bu yüzden yorum aldı. :-) –

cevap

5

Orijinal yazının yeterince iyi çalıştığını önerdiği gibi görünüyor. PEP, 307 okur için ne de

:

__getstate__ yöntem nesnenin kendisine bakmadan nesnenin durumunu temsil eden bir picklable değeri döndürmelidir.

Ben sadece __getstate__ yöntem basitçe (unpickleable) orijinal nesneye işaret etmeyen bir temsilini döndürür gerektiği anlamına gelir anlıyoruz. Böylece, orijinal (çıkarılmamış) nesneye yapılan bir başvuru yapılmadığı sürece, kendisine başvuran bir nesnenin döndürülmesi iyidir.

İlgili konular