我想序列化机器A和机器上反序列化B中的蟒蛇拉姆达。 有一对夫妇的与明显的问题:
- 咸菜模块不序列化或反序列化的代码。 只序列化的类/方法/函数的名称
- 一些我找到与谷歌的答案建议使用低级别的名帅模块的序列化拉姆达的func_code属性,但是他们没有说明如何人们可以从反序列化对象的代码重构一个函数对象
- marhshal(l.func_code)将不会与序列化导致的检测当一个给定的λ确实需要关闭,并警告说,他正试图序列化一个使用了闭拉姆达用户的问题拉姆达有关的关闭
因此,我的问题(S):
- 如何将一个重建从反序列化(demarshaled)码对象的功能?
- 如何将一个检测给定的λ不会没有相关的关闭正常工作?
出人意料的是,检查拉姆达是否没有其相关堵口其实是相当容易的。 按照数据模型文档 ,你可以检查func_closure
属性:
>>> 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
>>>
然后序列化+装载拉姆达是相当直截了当:
>>> 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.
请注意,您还可以提供封闭......这意味着你甚至可以序列化老功能的关闭,然后在另一端加载它:)
我不知道你想做什么,但你可以尝试萝 。 莳萝可序列化和反序列化lambda表达式,我相信也适用于内封闭lambda表达式。 泡菜API是它的API的一个子集。 要使用它,只是“进口莳萝泡菜为”去了解您的业务酸洗东西。
>>> import dill
>>> testme = lambda x: lambda y:x
>>> _testme = dill.loads(dill.dumps(testme))
>>> testme
<function <lambda> at 0x1d92530>
>>> _testme
<function <lambda> at 0x1d924f0>
>>>
>>> def complicated(a,b):
... def nested(x):
... return testme(x)(a) * b
... return nested
...
>>> _complicated = dill.loads(dill.dumps(complicated))
>>> complicated
<function complicated at 0x1d925b0>
>>> _complicated
<function complicated at 0x1d92570>
莳萝注册它的类型分为pickle
注册表,所以如果你有一个使用一些黑盒代码pickle
,你不能编辑它,然后只导入莳萝能神奇地度过,即使没有的Monkeypatching第三方代码工作。 或者,如果你想发送的电线为“蟒蛇形象”整个解释器会话,莳萝也可以这样做。
>>> # continuing from above
>>> dill.dump_session('foobar.pkl')
>>>
>>> ^D
dude@sakurai>$ python
Python 2.7.5 (default, Sep 30 2013, 20:15:49)
[GCC 4.2.1 (Apple Inc. build 5566)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> dill.load_session('foobar.pkl')
>>> testme(4)
<function <lambda> at 0x1d924b0>
>>> testme(4)(5)
4
>>> dill.source.getsource(testme)
'testme = lambda x: lambda y:x\n'
您可以轻松地在SSH发送图像到另一台计算机,并开始在那里你离开那里,只要有泡菜的版本兼容性和有关Python改变和正在安装的东西平时的告诫。 如图所示,还可以提取在前一交易日中定义的拉姆达的来源。
莳萝也有一些很好的工具,帮助您了解是什么原因导致你的酸洗当你的代码没有失败。