2015-03-25 43 views
1

我發現這個職位相當的答案:Is there an easy way to pickle a python function (or otherwise serialize its code)?完美序列化功能在python

然而,恢復的功能似乎從原來的一個,它失敗我的測試略有不同。

這裏的示例代碼:

import marshal 

# serialize 
f1 = lambda x: x == 0 
c1 = marshal.dumps(f1.func_code) 

# deserialize 
f2 = types.FunctionType(c1, globals()) 

# test 
c1 = marshal.dumps(f1.func_code) 
c2 = marshal.dumps(f2.func_code) 
assert c1 == c2  # fails 

你有什麼想法如何提高序列化/反序列化,以消除這種扭曲?

或有關平等測試部分的任何建議? PS:只考慮簡單的lambda表達式,但不包含複雜的閉包或普通函數。

回答

1

事情是你不能直接比較函數變量,除非它們都引用同一個對象。相反,您應該比較code對象。

import types 

original = lambda x: x == 0 
code = original.func_code 
recovered = types.FunctionType(code, globals()) 

print(original == recovered) 
print(original.func_code == recovered.func_code) 

輸出:

False 
True 

讓我們添加一些清晰度。

a = lamdba : 1 
aa = a 
b = lambda : 1 
c = lambda : 2 

print(a == b) 
print(a == aa) 
print(a.func_code == b.func_code) 
print(a.func_code == c.func_code) 

輸出:

False 
True 
True 
False 

編輯。我已經用你的函數和marshal序列化測試過了。完美的工作。

import marshal 
import types 

f = lambda x: x == 0 

with open("test", "rw") as temp: 
    marshal.dump(f.func_code, temp) 
    ff = types.FunctionType(marshal.loads(temp.read()), globals()) 

print(f.func_code == ff.func_code) 

輸出

True 
+0

OK,似乎元帥做了一些奇怪的事情,因爲 marshal.dumps(original.func_code)== marshal.dumps(recovered.func_code) 個返回False 更確切地說,marshal.loads(marshal.dumps(original.func_code))== original.func_code返回False – Sam 2015-03-25 09:03:22

+0

@Sam那麼,它適用於我。我已經爲答案添加了一個示例。 – 2015-03-25 09:28:56