问题
I found a considerable answer from this post: Is there an easy way to pickle a python function (or otherwise serialize its code)?
however, the restored function seems slightly different from the original one, which fails my test.
Here's the sample 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
Do you have any idea how to improve the serialization/deserialization to eliminate this distortion?
Or any suggestion on equality test part?
PS: take account of only simple lambda but not complex closure or ordinary function.
回答1:
The thing is you can't directly compare function variables unless they both reference the same object. Instead, you should compare code
objects.
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)
Output:
False
True
Let's add some clarity.
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)
Output:
False
True
True
False
Edit. I've tested this with your function and marshal
serialization. Works perfectly fine.
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)
Output
True
来源:https://stackoverflow.com/questions/29249347/perfectly-serialize-a-function-in-python