当前位置:  开发笔记 > 编程语言 > 正文

Python序列化词法闭包?

如何解决《Python序列化词法闭包?》经验,为你挑选了2个好方法。

有没有办法使用标准库在Python中序列化词法闭包?泡菜和元帅似乎不适用于词法封闭.我真的不关心二进制与字符串序列化等细节,它只需要工作.例如:

def foo(bar, baz) :
    def closure(waldo) :
        return baz * waldo
    return closure

我希望能够将闭包实例转储到文件中并将其读回.

编辑:可以解决这个问题的一个相对明显的方法是使用一些反射技巧将词法闭包转换为类对象,反之亦然.然后可以转换为类,序列化,反序列化,转换回闭包.哎呀,鉴于Python是鸭子类型,如果你重载类的函数调用操作符使它看起来像一个函数,你甚至不需要将它转换回闭包,使用它的代码不会知道区别.如果有任何Python反射API大师,请说出来.



1> dan mackinla..:

PiCloud发布了一个开源(LGPL)pickler,可以处理函数关闭和更多有用的东西.它可以独立于云计算基础设施使用 - 它只是一个普通的选择器.这里记录了整个shebang ,您可以通过'pip install cloud'下载代码.无论如何,它做你想要的.让我们通过酸洗一个闭包来证明:

import pickle
from StringIO import StringIO

import cloud

# generate a closure
def foo(bar, baz):
    def closure(waldo):
        return baz * waldo
    return closure
closey = foo(3, 5)

# use the picloud pickler to pickle to a string
f = StringIO()
pickler = cloud.serialization.cloudpickle.CloudPickler(f)
pickler.dump(closey)

#rewind the virtual file and reload
f.seek(0)
closey2 = pickle.load(f)

现在我们有了closey原始闭包,以及closey2从字符串序列化中恢​​复的闭包.我们来试试吧吧.

>>> closey(4)
20
>>> closey2(4)
20

美丽.该模块是纯粹的python-你可以打开它,轻松看看是什么让魔术发挥作用.(答案是很多代码.)



2> Greg Ball..:

如果你只是使用一个__call__方法开始的类,它应该可以顺利使用pickle.

class foo(object):
    def __init__(self, bar, baz):
        self.baz = baz
    def __call__(self,waldo):
        return self.baz * waldo

另一方面,将闭包转换为在运行时创建的新类的实例的hack将无法工作,因为pickle处理类和实例的方式. pickle不存储课程; 只有模块名称和类名.回读一个实例或类时,它会尝试导入模块并在其中找到所需的类.如果你使用了即时创建的课程,那你就不走运了.

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有