2013-06-11 44 views
1

誰能告訴我爲什麼我的代碼和函數序列化處理程序不在下面工作? copyreg模塊對我來說很陌生,不清楚下面的代碼是否寫得正確。這裏是否正確使用了copyreg模塊?

>>> import pickle, copyreg, types, marshal 
>>> def average(*args): 
    return sum(args)/len(args) 

>>> average_dump = pickle.dumps(average) 
>>> del average 
>>> average = pickle.loads(average_dump) 
Traceback (most recent call last): 
    File "<pyshell#31>", line 1, in <module> 
    average = pickle.loads(average_dump) 
AttributeError: 'module' object has no attribute 'average' 
>>> copyreg.pickle(types.CodeType, 
      lambda code: (marshal.loads, (marshal.dumps(code),)), 
      marshal.loads) 
>>> up = lambda co, ns, de, cl: types.FunctionType(co, globals(), na, de, cl) 
>>> copyreg.pickle(types.FunctionType, 
      lambda function: (up, (function.__code__, 
         function.__name__, 
         function.__defaults__, 
         function.__closure__)), 
      up) 
>>> def average(*args): 
    return sum(args)/len(args) 

>>> average_dump 
b'\x80\x03c__main__\naverage\nq\x00.' 
>>> pickle.dumps(average) 
b'\x80\x03c__main__\naverage\nq\x00.' 
>>> del average; average = pickle.loads(average_dump) 
Traceback (most recent call last): 
    File "<pyshell#39>", line 1, in <module> 
    del average; average = pickle.loads(average_dump) 
AttributeError: 'module' object has no attribute 'average' 

我的期望是,如果註冊的功能都正常工作,那麼代碼和函數對象將被序列化。如果按預期工作,則取消功能也是可能的。


編輯:子類Picklerthis answer建議。似乎也沒有幫助。示例中的函數仍由名稱序列化,而不是來自copyreg模塊的處理程序。

>>> import pickle, copyreg, types, marshal 
>>> copyreg.pickle(types.CodeType, 
      lambda code: (marshal.loads, (marshal.dumps(code),)), 
      marshal.loads) 
>>> up = lambda co, ns, de, cl: types.FunctionType(co, globals(), na, de, cl) 
>>> copyreg.pickle(types.FunctionType, 
      lambda function: (up, (function.__code__, 
         function.__name__, 
         function.__defaults__, 
         function.__closure__)), 
      up) 
>>> class MyPickler(pickle.Pickler): 
    def __init__(self, *args): 
     super().__init__(*args) 
     self.dispatch_table = copyreg.dispatch_table 


>>> def average(*args): 
    return sum(args)/len(args) 

>>> x = io.BytesIO(); y = MyPickler(x) 
>>> y.dump(average) 
>>> x.getvalue() 
b'\x80\x03c__main__\naverage\nq\x00.' 

回答

-1

功能的不能用價值來醃製:

注意功能(內置和用戶定義的)由「完全合格」的名字引用,而不是值醃製。這意味着,只有函數名進行酸洗,與功能英寸無論是函數的代碼所定義的模塊的名稱一起,也沒有任何其功能屬性都酸洗。因此,定義模塊必須可以在unpickling環境中導入,並且模塊必須包含指定的對象,否則會引發異常。

http://docs.python.org/2/library/pickle.html#what-can-be-pickled-and-unpickled

+0

我知道他們是如何醃製目前,但爲何'copyreg'模塊不聽從我的指令,以使用新的處理程序? –

+0

我誤解了,對不起。也許試試這個:http://stackoverflow.com/a/2933605/257418 – Lynn