加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 如何序列化递归函数?

发布时间:2020-12-20 13:36:37 所属栏目:Python 来源:网络整理
导读:假设我有一个通过其闭包递归的函数: def outer(): def fact(n): return 1 if n == 0 else n * fact(n - 1) return fact 我现在想要序列化该函数并使用types.FunctionType重构它: import pickle,marshal,copyreg,typesdef make_cell(value): return (lambda
假设我有一个通过其闭包递归的函数:

def outer():
    def fact(n):
        return 1 if n == 0 else n * fact(n - 1)
    return fact

我现在想要序列化该函数并使用types.FunctionType重构它:

import pickle,marshal,copyreg,types

def make_cell(value):
    return (lambda: value).__closure__[0]

def make_function(*args):
    return types.FunctionType(*args)

copyreg.pickle(types.CodeType,lambda code: (marshal.loads,(marshal.dumps(code),)))
copyreg.pickle(type((lambda i=0: lambda: i)().__closure__[0]),lambda cell: (make_cell,(cell.cell_contents,)))
copyreg.pickle(types.FunctionType,lambda fn: (make_function,(fn.__code__,{},fn.__name__,fn.__defaults__,fn.__closure__)))

buf = pickle.dumps(outer())
fn = pickle.loads(buf)

这适用于普通的闭包,但实际上它会导致无限递归,因为pickle试图在其闭包中序列化事实.在pickle中处理递归数据结构的常用方法是在构造和初始化之间记忆对象,但是函数对象是不可变的,如fn .__ closure__(元组)和单元对象:

>>> cell = (lambda i=0: lambda: i)().__closure__[0]
>>> cell.cell_contents = 5
Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
AttributeError: attribute 'cell_contents' of 'cell' objects is not writable

据推测,在正常代码中构造递归函数时,语言必须做类似的事情,因为函数对象在构造之前不能放在它的闭包中.构建我错过的递归函数是否有一些魔力?

解决方法

闭包绑定到一个自由变量,而不是它的值.对于自引用闭包,所有Python需要做的是首先为自由事实名创建一个闭包(尚未绑定到任何东西),用闭包创建函数对象,然后将事实绑定到该对象.

因此,您需要将创建闭包和函数组合到同一个外部函数中,这样您就可以为函数绑定的名称创建一个闭包:

def create_closure_and_function(*args):
    func = None
    def create_function_closure():
         return func

    closure = create_function_closure.__closure__
    func = types.FunctionType(*args[:-1] + [closure])
    return func

为了使这个工作与unpickling你必须循环关闭参数(args [-1])并检测有递归的位置,并用create_function_closure .__ closure __ [0]替换那个项目,我想.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读