在python中完美地序列化一个函数

时间:2015-03-25 06:59:46

标签: python function serialization equality

我在这篇文章中找到了相当多的答案:Is there an easy way to pickle a python function (or otherwise serialize its code)?

然而,恢复的功能似乎与原来的功能略有不同,这在我的测试中失败了。

以下是示例代码:

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 个答案:

答案 0 :(得分: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