2013-10-31 21 views
1

我遇到了泡菜的麻煩:我有一個棘手的用例,我沒有找回我醃製的對象的副本。如果我開始泡菜失去了我的一個論點

class OneArg(object): 
    def __init__(self, somearg, *args, **kwargs): 
     print "In OneArgs's init with args={} and kwargs={}".format(args, kwargs) 
     self._somearg = somearg 
     super(OneArg, self).__init__(*args, **kwargs) 

class OneArgSubclass(OneArg, OrderedDict): 
    def __init__(self, *args, **kwargs): 
     print "In OneArgSubclass's init with args={} and kwargs={}".format(args, kwargs) 
     super(OneArgSubclass, self).__init__(*args, **kwargs) 


def verbose_pickle_dumps (obj): 
    result = pickle.dumps(obj) 
    print result 
    return result 


oas = OneArgSubclass("SOMEARG") 
oas['spam'] = 'eggs' 
oas_red = pickle.loads(verbose_pickle_dumps(oas)) 
print "oas_red.keys():", oas_red.keys() 

這裏的輸出我得到:

In OneArgSubclass's init with args=('SOMEARG',) and kwargs={} 
In OneArgs's init with args=() and kwargs={} 
oas.keys(): ['spam'] 

c__main__ 
OneArgSubclass 
p0 
((lp1 
(lp2 
S'spam' 
p3 
aS'eggs' 
p4 
aatp5 
Rp6 
(dp7 
S'_somearg' 
p8 
S'SOMEARG' 
p9 
sb. 

In OneArgSubclass's init with args=([['spam', 'eggs']],) and kwargs={} 
In OneArgs's init with args=() and kwargs={} 
oas_red.keys(): [] 

我可以看到,當我醃美洲國家組織,「垃圾郵件」 /「蛋」鍵/值對在那裏, _somearg的價值也是如此。請注意,字符串「OrderedDict」不會出現,但是。當我嘗試從pickle加載oas時,它不會接收字符串'SOMEARG',因此字典的內容最終會以_somearg的值結尾。

我看了,oas既沒有__getinitargs __()也沒有__getnewargs __()。如果我使用常規字典而不是OrderedDict,代碼就可以工作(並且醃製代表看起來相當不同,包括提及'copy_reg'),所以我認爲問題可能是pickle和OrderedDict之間的兼容性。但是,當我單獨使用OrderedDict時,pickle可以正常工作。

回答

1

當你醃製的東西有several different methods可用於提取數據重新創建對unpickling。您正在運行中的問題是OrderedDict定義它們(__reduce__)之一,但它返回與您的__init__兼容 - 所以你需要編寫自己:

def __reduce__(self): 
    return (self.__class__, (self._somearg, tuple(self.items()))) 
0

您可能希望爲您的班級實施__repr__()方法,如下所示:http://bytes.com/topic/python/answers/781057-pickle-instance-custom-class

在他們的榜樣,他們從OrderedDict類,並實現了一個__repr__()方法這樣

def __repr__(self): 
     return '{%s}' % ', '.join([': '.join([repr(k),str(v)]) \ 
            for k,v in zip(self.keys(), self.values())]) 

上課的時候__init()__代表

class OrderedDict(dict): 

    def __init__(self, d = None): 
     self._keys = [] 
     if d == None: d = {} 
     self.update(d)