perfectly serialize a function in python

别等时光非礼了梦想. 提交于 2019-12-11 14:25:17

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!