我在这篇文章中找到了相当多的答案: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但不考虑复杂的闭包或普通函数。
答案 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