Python:腌制嵌套函数 [英] Python: pickling nested functions

查看:102
本文介绍了Python:腌制嵌套函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用示例

def foo(a):
    def bar(b):
        return a+b
    return bar

d = {1:foo(1), 2:foo(2)}

看来,泡菜模块不能与模块范围内未定义的功能一起使用,因此酸洗'd'将不起作用.我还有其他应考虑的酸洗机制吗?

解决方案

恐怕您不能腌制嵌套函数.

pickle模块按名称序列化功能.也就是说,如果模块mymodule中具有函数myfunc,则只需保存名称mymodule.myfunc,并在反序列化时再次查找它. (这是一个重要的安全性和兼容性问题,因为它保证了反序列化的代码对函数使用自己的定义,而不是可能被破坏或作废的原始定义.)

A,pickle不能使用嵌套函数来完成此操作,因为无法直接通过名称来寻址它们.例如,不能从foo外部访问您的bar函数.

如果您需要一个像函数一样可序列化的对象,则可以使用__call__方法来创建一个类:

class foo(object):
    def __init__(self, a):
        self.a = a
    def __call__(self, b): # the function formerly known as "bar"
        return self.a + b

这就像问题中的嵌套函数一样工作,并且对pickle不会造成任何问题.不过请注意,在反序列化foo实例时,需要具有相同的类定义.

Using the example

def foo(a):
    def bar(b):
        return a+b
    return bar

d = {1:foo(1), 2:foo(2)}

It appears that pickle module will not work with a function not defined at the module scope, so pickling 'd' will not work. Is there another pickling mechanism available that I should consider?

解决方案

I'm afraid that you can't pickle nested functions.

The pickle module serializes functions by name. That is, if you have a function myfunc in a module mymodule it simply saves the name mymodule.myfunc and looks it up again when unserializing. (This is an important security and compatibility issue, as it guarantees that the unserializing code uses its own definition for the function, rather than the original definition which might be compromised or obsolete.)

Alas, pickle can't do that with nested functions, because there's no way to directly address them by name. Your bar function, for instance, can't be accessed from outside of foo.

If you need a serializable object that works like a function, you can instead make a class with a __call__ method:

class foo(object):
    def __init__(self, a):
        self.a = a
    def __call__(self, b): # the function formerly known as "bar"
        return self.a + b

This works just like the nested functions in the question, and should pose no problem to pickle. Do be aware though, that you'll need to have the same class definition available when you unserialize a foo instance.

这篇关于Python:腌制嵌套函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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