import types import marshal # Function serialization / deserialixation def func_dump(func): '''Serialize user defined function.''' code = marshal.dumps(func.__code__).decode('raw_unicode_escape') defaults = func.__defaults__ if func.__closure__: closure = tuple(c.cell_contents for c in func.__closure__) else: closure = None return (code, defaults, closure) def func_load( code, defaults=None, closure=None, globs=None, ): '''Deserialize user defined function.''' if isinstance(code, (tuple, list)): # unpack previous dump (code, defaults, closure) = code code = marshal.loads(code.encode('raw_unicode_escape')) if closure is not None: closure = func_reconstruct_closure(closure) if globs is None: globs = globals() return types.FunctionType(code, globs, name=code.co_name, argdefs=defaults, closure=closure) def func_reconstruct_closure(values): '''Deserialization helper that reconstructs a closure.''' nums = range(len(values)) src = ['def func(arg):'] src += [' _%d = arg[%d]' % (n, n) for n in nums] src += [' return lambda:(%s)' % ','.join(['_%d' % n for n in nums]), ''] src = '\n'.join(src) try: exec (src, globals()) except: raise SyntaxError(src) return func(values).__closure__ def serialize_function(func): if isinstance(func, types.LambdaType): function = func_dump(func) function_type = 'lambda' else: function = func.__name__ function_type = 'function' return (function_type, function) def deserialize_function(txt): (function_type, function) = txt if function_type == 'function': return globals()[function] else: return func_load(function, globs=globals())