The first investigation is to check whether we can serialize and deserialize lambda functions. I basically took the example from here: http://stackoverflow.com/questions/11878300/serializing-and-deserializing-lambdas
In [3]:
import marshal, types
# a simple square function with a lambda function
square = lambda value: value**2
print(square, square(32))
# serializing the lambda function
square_code_serialized = marshal.dumps(square.func_code)
print(square_code_serialized)
# desersializing the lambda function
square_reloaded = types.FunctionType(marshal.loads(square_code_serialized), globals())
print(square_reloaded, square_reloaded(32))
In [11]:
import json
json_serialized = json.dumps({'code': square_code_serialized})
print(json_serialized)
json_deserialized = json.loads(json_serialized)
json_deserialized['code'] = types.FunctionType(marshal.loads(json_deserialized['code']), globals())
print(json_deserialized, json_deserialized['code'](32))
Basicall I'm quite comfortable with the encoder class except that I miss a is_lambda function as builtin. Unfortunately the decoder class is not as straight forward. With a hook function I got it also more by trying then by refering to a documentation. A working example but not yet convinced to put it into the concept-py code base.
In [47]:
class LambdaEncoder(json.JSONEncoder):
def default(self, o):
# TODO: missing a is_lambda function ...
LAMBDA = lambda:0
if isinstance(o, type(LAMBDA)):
return marshal.dumps(o.func_code)
return json.JSONEncoder.default(self, o)
def lambda_decoder(o):
"""
a bit tricky since I'm relying on what I have seen when dumping
the serialized lambda code. But since I have no better solution ...
""""
for pos, entry in enumerate(o):
key, value = entry[0], entry[1]
if str(value).find("lambda") >= 0:
o[pos] = (key, types.FunctionType(marshal.loads(value), globals()))
return dict(o)
# TODO: using a class for encoding and a function for decoding ... should be harmonized somehow.
json_serialized = json.dumps({'code': lambda value: value**2, 'value': 12334},cls=LambdaEncoder)
json_deserialized = json.loads(json_serialized, object_pairs_hook=lambda_decoder)
print(json_deserialized['code'](32))
The problems mentioned are Python versions and how they handle internals like square.func_code which does not exist in Python 3.x
In [ ]: