有没有一种方法可以使用标准库序列化Python中的词法闭包?pickle和marshal似乎不能处理词汇闭包。我真的不关心二进制与字符串序列化的细节,它只需要工作。例如:
def foo(bar, baz) :
def closure(waldo) :
return baz * waldo
return closure
我只希望能够将闭包实例转储到一个文件中并读回它们。在
编辑: 解决这个问题的一个相对明显的方法是使用一些反射黑客将词汇闭包转换为类对象,反之亦然。然后可以转换为类、序列化、取消序列化、转换回闭包。如果Python是duck类型的,那么如果重载类的函数调用运算符使其看起来像函数,那么甚至不需要将它转换回闭包,并且使用它的代码也不知道区别。如果有Python反射API专家,请大声说出来。在
如果您只使用一个带有
__call__
方法的类,那么它应该可以顺利地与pickle
一起工作。在另一方面,由于
pickle
处理类和实例的方式,将闭包转换为在运行时创建的新类的实例的黑客行为是行不通的。pickle
不存储类;只存储模块名和类名。当读回一个实例或类时,它尝试导入模块并在其中找到所需的类。如果你使用了一个动态创建的类,那你就倒霉了。在是的!我明白了(至少我认为是这样的)——这是一个更普遍的函数酸洗问题。Python太棒了:),我通过dir()函数和几个web搜索找到了它的大部分内容。很高兴解决了这个问题,我也需要它。在
我还没有做过很多测试来测试这种代码的健壮性(嵌套的fcn等等),如果有人能找到如何钩住Python以便函数可以自动地被pickle(例如,它们有时可能是闭包参数)那就更好了。在
Cython模块泡菜_fcn.pyx公司在
Python文件
^{pr2}$干杯,
尼古拉斯
编辑-对于真实世界的案例,需要更强大的全局处理。功能代码.co_names列出全局名称。在
PiCloud发布了一个开源(LGPL)pickler,它可以处理函数闭包和更多有用的东西。它可以独立于他们的云计算基础设施使用——这只是一个普通的泡菜。整个shebang都有文档记录here,您可以通过“pip install cloud”下载代码。不管怎样,它做你想做的。让我们通过酸洗来证明:
现在我们有了
^{pr2}$closey
,原始闭包,closey2
,这是从字符串序列化中恢复的闭包。让我们测试一下很漂亮。这个模块是纯python的,你可以打开它,很容易地看到是什么让魔法起作用。(答案是大量代码。)
相关问题 更多 >
编程相关推荐