序列化和反序列化lambda [英] serializing and deserializing lambdas

查看:259
本文介绍了序列化和反序列化lambda的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在机器A上序列化并在机器B上反序列化python lambda.有两个明显的问题:

I would like to serialize on machine A and deserialize on machine B a python lambda. There are a couple of obvious problems with that:

    pickle模块不会序列化或反序列化代码.它仅序列化类/方法/函数的名称
  • 我在Google上找到的一些答案建议使用低级编组模块对lambda的func_code属性进行序列化,但它们未能描述如何从反序列化的代码对象中重建函数对象
  • marhshal(l.func_code)不会序列化与lambda相关联的闭包,从而导致检测以下问题:检测给定的lambda何时确实需要闭包,并警告用户他正尝试序列化使用闭包的lambda
  • the pickle module does not serialize or deserialize code. It only serializes the names of classes/methods/functions
  • some of the answers I found with google suggest the use of the low-level marshal module to serialize the func_code attribute of the lambda but they fail to describe how one could reconstruct a function object from the deserialized code object
  • marhshal(l.func_code) will not serialize the closure associated with the lambda which leads to the problem of detecting when a given lambda really needs a closure and warning the user that he is trying to serialize a lambda that uses a closure

因此,我的问题:

  • 一个人如何从反序列化(已分组)的代码对象中重构一个函数?
  • 如果没有关联的闭包,如何检测给定的lambda无法正常工作?

推荐答案

令人惊讶的是,检查lambda是否可以在没有关联的闭包的情况下工作是很容易的.根据数据模型文档,您只需检查func_closure属性:

Surprisingly, checking whether a lambda will work without its associated closure is actually fairly easy. According to the data model documentation, you can just check the func_closure attribute:


>>> def get_lambdas():
...     bar = 42
...     return (lambda: 1, lambda: bar)
...
>>> no_vars, vars = get_lambdas()
>>> print no_vars.func_closure
None
>>> print vars.func_closure
(<cell at 0x1020d3d70: int object at 0x7fc150413708>,)
>>> print vars.func_closure[0].cell_contents
42
>>>

然后序列化+加载lambda相当简单:

Then serializing + loading the lambda is fairly straight forward:


>>> import marshal, types
>>> old = lambda: 42
>>> old_code_serialized = marshal.dumps(old.func_code)
>>> new_code = marshal.loads(old_code_serialized)
>>> new = types.FunctionType(new_code, globals())
>>> new()
42

值得阅读FunctionType的文档:


function(code, globals[, name[, argdefs[, closure]]])

Create a function object from a code object and a dictionary.
The optional name string overrides the name from the code object.
The optional argdefs tuple specifies the default argument values.
The optional closure tuple supplies the bindings for free variables.

请注意,您也可以提供闭包…这意味着您甚至可以序列化旧函数的闭包,然后在另一端加载它:)

Notice that you can also supply a closure… Which means you might even be able to serialize the old function's closure then load it at the other end :)

这篇关于序列化和反序列化lambda的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆