【问题标题】:perfectly serialize a function in python完美序列化python中的函数
【发布时间】:2015-05-28 18:01:18
【问题描述】:

我从这篇文章中找到了相当多的答案:Is there an easy way to pickle a python function (or otherwise serialize its code)?

但是,恢复的功能似乎与原来的功能略有不同,我的测试失败了。

示例代码如下:

import marshal

# serialize
f1 = lambda x: x == 0
c1 = marshal.dumps(f1.func_code)

# deserialize
f2 = types.FunctionType(c1, globals())

# test
c1 = marshal.dumps(f1.func_code)
c2 = marshal.dumps(f2.func_code)
assert c1 == c2     # fails

您知道如何改进序列化/反序列化以消除这种失真吗?

或者对相等测试部分有什么建议?

PS:只考虑简单的 lambda,不考虑复杂的闭包或普通函数。

【问题讨论】:

    标签: python function serialization equality


    【解决方案1】:

    问题是你不能直接比较函数变量,除非它们都引用同一个对象。相反,您应该比较 code 对象。

    import types
    
    original = lambda x: x == 0
    code = original.func_code
    recovered = types.FunctionType(code, globals())
    
    print(original == recovered)
    print(original.func_code == recovered.func_code)
    

    输出:

    False
    True
    

    让我们添加一些清晰度。

    a = lamdba : 1
    aa = a
    b = lambda : 1
    c = lambda : 2
    
    print(a == b)
    print(a == aa)
    print(a.func_code == b.func_code)
    print(a.func_code == c.func_code)
    

    输出:

    False
    True
    True
    False
    

    编辑。我已经用你的函数和marshal 序列化测试了这个。工作得很好。

    import marshal
    import types 
    
    f = lambda x: x == 0
    
    with open("test", "rw") as temp:
        marshal.dump(f.func_code, temp)
        ff = types.FunctionType(marshal.loads(temp.read()), globals())
    
    print(f.func_code == ff.func_code)
    

    输出

    True
    

    【讨论】:

    • 好的,marshal 似乎做了一些奇怪的事情,因为 marshal.dumps(original.func_code) == marshal.dumps(recovered.func_code) 更准确地返回 False,marshal.loads(marshal.dumps( original.func_code)) == original.func_code 返回 False
    • @Sam 好吧,它对我有用。我在答案中添加了一个示例。
    猜你喜欢
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多