2

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.

Community
  • 1
  • 1
Sam
  • 133
  • 10

1 Answers1

2

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
Eli Korvigo
  • 10,265
  • 6
  • 47
  • 73
  • ok, it seems that marshal did something strange, as marshal.dumps(original.func_code) == marshal.dumps(recovered.func_code) returns False more exactly, marshal.loads(marshal.dumps(original.func_code)) == original.func_code returns False – Sam Mar 25 '15 at 09:03
  • @Sam Well, it works for me. I've added an example to the answer. – Eli Korvigo Mar 25 '15 at 09:28